0

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();
}
Michał Krzywański
  • 15,659
  • 4
  • 36
  • 63
0day
  • 103
  • 1
  • 10
  • 1
    have a look at [this](https://stackoverflow.com/questions/40236689/is-assigning-a-frequently-used-field-to-a-local-variable-more-efficient) for possible answer. – Michał Krzywański Aug 01 '19 at 13:49

1 Answers1

0

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
Borislav Stoilov
  • 3,247
  • 2
  • 21
  • 46
  • sorry, maybe I didn't described clearly. what I mean was final ReentrantLock putLock = this.putLock; final AtomicInteger count = this.count; – 0day Aug 01 '19 at 13:37
  • I see, well my guess is that they wanted to make the code more reliable. Those final statements will prevent anyone from reassigning the variables in the method, you often see such thing in code that is maintained by big teams – Borislav Stoilov Aug 01 '19 at 13:43