java - 管理多个锁

标签 java concurrency

我遇到以下情况:我正在同时处理具有给定键的请求。我可以同时处理任意数量的请求,只要进行中的每个键都是唯一的。

我是 Java 并发方面的新手。一定有一些模式/实用程序/现有问题,但我不知道要搜索什么。希望有人能为我指明正确的方向,或对我目前所做的发表评论。

这个类管理锁:

class LockMap<K> {
    private Map<K, Object> locks = new HashMap<>();

    void acquireLock(K key) throws InterruptedException {
        Object lockObj;
        synchronized (locks) {
            lockObj = locks.get(key);

            if (lockObj == null) lockObj = new Object();

            locks.put(key, lockObj);
        }

        synchronized (lockObj) {
            lockObj.wait();
        }
    }

    void releaseLock(K key) {
        Object lockObj;
        synchronized (locks) {
            lockObj = locks.get(key);
            locks.remove(key);
        }

        if (lockObj != null) {
            synchronized (lockObj) {
                lockObj.notify();
            }
        }
    }
}

然后我像这样使用锁管理器:

// lockMap is instance of LockMap shared across all threads
void doSomething(K key) {
    lockMap.acquireLock(key);
    try {
        // something
    } finally {
        lockMap.releaseLock(key);
    }
}

这是正确的做法吗?

最佳答案

这个怎么样:

创建一个 ConcurrentHashMap<K,Semaphore>

ConcurrentMap<K, Semaphore> myMap = new ConcurrentHashMap<>();

在你的doSomething()方法,使用 putIfAbsent()方法 to 将具有一个许可的信号量添加到 map ,仅当键不存在于 map 中时。

随后执行 get()在键上获取该键的信号量,然后做你的事情。完成后释放信号量。

void doSomething(K key) {
     myMap.putIfAbsent(key, new Semaphore(1));
     Semaphore s = myMap.get(myKey);
     s.aquire();
     try {
     // do stuff
     } finally {
       s.release();
     }
 }

这个方案唯一真正的问题是如果你的键列表会无限增长,我没有一个很好的无竞争条件的策略来从 map 中删除信号量。 (但如果你知道你会一遍又一遍地重复使用相同的键,或者列表会增长缓慢,那么也许这没问题。)

关于java - 管理多个锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21286831/

相关文章:

java - 在 Java 中模拟 wget --no-check-certificate --secure-protocol=TLSv1

ios - performSelector:withObject:afterDelay: 在 NSOperation 中

java - 卡在受信号量保护的交互中

java - 错误: java. lang.RuntimeException,如何正确从 Intent 中获取额外内容?

java - Twitter4J 上最多 20 个好友信息

java - 显示可编辑整数数组的最佳格式化程序? (可以从0开始)

java - 通过 SSH 信任使用 DefaultSftpSessionFactory 进行 SFTP 会引发异常

Java REST 优化数据结构访问

java - 仅有一个Java使用者和生产者线程的并发队列

java - ExecutorService线程安全