首页 > 解决方案 > 为 putLock 和 count 制作本地副本的目的是什么?

问题描述

这段代码来自jdk LinkedBlockingQueue,我想知道为什么他们在这里制作局部变量而不是直接使用它?

final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;


public void put(E e) throws InterruptedException {
    if (e == null) throw new NullPointerException();
    final int c;
    final Node<E> node = new Node<E>(e)
    final ReentrantLock putLock = this.putLock;
    final AtomicInteger count = this.count;
    putLock.lockInterruptibly();
    try {
        /*
         * Note that count is used in wait guard even though it is
         * not protected by lock. This works because count can
         * only decrease at this point (all other puts are shut
         * out by lock), and we (or some other waiting put) are
         * signalled if it ever changes from capacity. Similarly
         * for all other uses of count in other wait guards.
         */
        while (count.get() == capacity) {
            notFull.await();
        }
        enqueue(node);
        c = count.getAndIncrement();
        if (c + 1 < capacity)
            notFull.signal();
    } finally {
        putLock.unlock();
    }
    if (c == 0)
        signalNotEmpty();
}

标签: java

解决方案


Java 通过引用传递对象。在这种情况下,'e' 是对内存中某个对象的引用。如果您不在方法内复制它,变异操作将影响正在传递的对象,在这种情况下,这不是所需的行为。

想象一下这种情况:

Queue q = new LinkedBlockingQueue(..);
Node e = new Node(..);
q.put(e); // internal state of e is changed
//do something with e and potentially not knowing that is has changed

推荐阅读