锁里面的AtomicInteger有什么用
what is the use of AtomicInteger inside lock
在 java.util.concurrent.LinkedBlockingQueue.put() 方法的这一部分中,我认为不需要 AtomicInteger。考虑到 lock() 中只有一个线程。我说得对吗?
putLock.lockInterruptibly();
try {
while (count.get() == capacity) {
notFull.await();
}
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
我检查了很多问题,但找不到答案。我的问题:锁里面只有一个线程,为什么要在这里使用AtomicInteger
那里有两把锁:
private final ReentrantLock putLock = new ReentrantLock();
private final ReentrantLock takeLock = new ReentrantLock();
put
方法确实受到 putLock
的保护,但是访问 count
的任何其他线程仍然可以更新它(除非它是另一个 put
)。为确保它已正确更新,它必须是 Atomic
。
LinkedBlockingQueue
使用两个不同的锁,putLock
和 takeLock
允许并发的 put
和 take
操作在不阻塞彼此的情况下进行,假设队列中已经有节点但容量没有用完(或根本没有限制)。
所以在这种情况下,count
可能会被两个线程同时访问。由于消费者和生产者线程使用不同的锁,锁本身并没有在生产者和消费者之间建立必要的内存可见性保证,实际上是 count
的原子更新。
除此之外,还有非阻塞操作,如size()
或remainingCapacity()
无需持有锁即可访问count
。此外,一些操作,如 peek()
和 poll()
(没有超时)有一个捷径,在获取锁之前测试 count
是否为零,到 return null
计数为零时立即不锁定。
在 java.util.concurrent.LinkedBlockingQueue.put() 方法的这一部分中,我认为不需要 AtomicInteger。考虑到 lock() 中只有一个线程。我说得对吗?
putLock.lockInterruptibly();
try {
while (count.get() == capacity) {
notFull.await();
}
enqueue(node);
c = count.getAndIncrement();
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();
}
我检查了很多问题,但找不到答案。我的问题:锁里面只有一个线程,为什么要在这里使用AtomicInteger
那里有两把锁:
private final ReentrantLock putLock = new ReentrantLock();
private final ReentrantLock takeLock = new ReentrantLock();
put
方法确实受到 putLock
的保护,但是访问 count
的任何其他线程仍然可以更新它(除非它是另一个 put
)。为确保它已正确更新,它必须是 Atomic
。
LinkedBlockingQueue
使用两个不同的锁,putLock
和 takeLock
允许并发的 put
和 take
操作在不阻塞彼此的情况下进行,假设队列中已经有节点但容量没有用完(或根本没有限制)。
所以在这种情况下,count
可能会被两个线程同时访问。由于消费者和生产者线程使用不同的锁,锁本身并没有在生产者和消费者之间建立必要的内存可见性保证,实际上是 count
的原子更新。
除此之外,还有非阻塞操作,如size()
或remainingCapacity()
无需持有锁即可访问count
。此外,一些操作,如 peek()
和 poll()
(没有超时)有一个捷径,在获取锁之前测试 count
是否为零,到 return null
计数为零时立即不锁定。