what is the purpose make local copy for putLock and count?

This pice of code is from jdk’s LinkedBlockingQueue,
I’m wondering why they make local variable here instead of directly use it?

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();
}

1
Leave a Reply

avatar
1 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jason
Guest

Java passes objects by reference. In this case ‘e’ is an reference to some object in memory. If you don’t make a copy of it inside the method, the mutation operations will affect the object that is being passed, which in this case is not the desired behaviour.

Imagine this case:

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