当我们想使用 map.get(key).wait() 时,当值是 AtomicLong 时同步 map.get(key) 真的有意义吗?

Does it really make sense to synchronize map.get(key) while the value is a AtomicLong when we want to use map.get(key).wait()?

我想做的是实现一个特定于密钥的读写锁。如果该键上没有写入请求,则可以同时执行多个读取请求。可以同时执行对不同键的请求。 我使用 ConcurrentHashMap 来保存密钥并记录每个密钥的 运行 写入操作。

我的代码如下所示:

ConcurrentHashMap<String, AtomicInteger> count;
...
...
public void getLock(){
    synchronized (count.get(key)) {
        while (count.get(key).get() != 0) { // this means there are GET                                     
                                          requests running
            try {
                count.get(key).wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

思路是当一个新的线程要读的时候,首先要检查那个key上有没有写(如果count不为0)如果没有就可以继续,如果有就需要等待。 所以我想我必须使用 count.get(key).wait();。但是,Java 迫使我 synchronized (count.get(key)) 才能使用 wait() 方法。

我想知道在这里使用同步是否有意义,因为我已经使用了 AtomicInteger?

p.s。 我在后面的解锁方法中确实有notify()

我刚刚意识到为什么我仍然需要一个用于 AtomicInteger 的同步块。 所有评论以及 this link 都非常有用。

If the waiter didn't synchronize, then any old bit of code might change the predicate just before it goes to sleep, and then we're certainly in trouble.

所以即使它是 AtomicInteger(实际上,值的数据类型并不重要),就在等待之前,另一个线程可以更改它的值,这将是错误的。