内部锁定中AtomicInteger的用途是什么

时间:2017-07-13 11:00:29

标签: multithreading concurrency java-8 atomic

在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

2 个答案:

答案 0 :(得分:7)

LinkedBlockingQueue使用两个不同的锁putLocktakeLock,允许并发puttake操作继续进行而不会相互阻塞,假设存在已经是队列中的节点,但容量尚未耗尽(或根本不受限制)。

所以在这种情况下,count可以由两个线程同时访问。由于使用者和生产者线程使用不同的锁,因此锁本身不会在生产者和使用者之间建立必要的内存可见性保证,实际上它是count的原子更新。

除此之外,还有非阻止操作,例如size()remainingCapacity(),无需持有锁即可访问count。此外,某些操作(如peek()poll()(没有超时)都有一个快捷方式,在获取锁之前测试count为零,在没有锁定的情况下立即返回null当计数为零时。

答案 1 :(得分:5)

那里有两把锁:

private final ReentrantLock putLock = new ReentrantLock();

private final ReentrantLock takeLock = new ReentrantLock();

put方法确实受putLock保护,但访问count的任何其他线程仍然可以更新它(除非它是另一个put)。为确保正确更新,必须为Atomic