0

I am reading Java LinkedBlockingQueue source code, the place I don't understand is, the lock and cond variable are already initialized at the beginning, why assign them to new local variables in each function every time they are used? Here are the examples in the source code enter image description here

lock and cond_var initialized here

    /** The capacity bound, or Integer.MAX_VALUE if none */

    private final int capacity;


    /** Current number of elements */

    private final AtomicInteger count = new AtomicInteger();


    /**

     * Head of linked list.

     * Invariant: head.item == null

     */

    transient Node<E> head;


    /**

     * Tail of linked list.

     * Invariant: last.next == null

     */

    private transient Node<E> last;


    /** Lock held by take, poll, etc */

    private final ReentrantLock takeLock = new ReentrantLock();


    /** Wait queue for waiting takes */

    private final Condition notEmpty = takeLock.newCondition();


    /** Lock held by put, offer, etc */

    private final ReentrantLock putLock = new ReentrantLock();


    /** Wait queue for waiting puts */

    private final Condition notFull = putLock.newCondition();

examples of re-assign and using them

// example 1
private void signalNotEmpty() {

        final ReentrantLock takeLock = this.takeLock;

        takeLock.lock();

        try {

            notEmpty.signal();

        } finally {

            takeLock.unlock();

        }

    }

// example 2
public void put(E e) throws InterruptedException {

        if (e == null) throw new NullPointerException();

        // Note: convention in all put/take/etc is to preset local var

        // holding count negative to indicate failure unless set.

        int c = -1;

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

    }
PopCornnnn
  • 11
  • 2
  • 2
    This is done for performance and thread-safety reasons. I know there is a duplicate somewhere about this. – Mark Rotteveel Aug 05 '22 at 10:09
  • As an aside, if you're new to Java, I recommend not diving too deep into the sources of `java.util.concurrent`, as it is pretty advanced level stuff they're doing. – Mark Rotteveel Aug 05 '22 at 10:15
  • This was how I guess, but I don't see how, is there a more detailed explanation? I tried to implement this in c, but without re-assignment, it worked. – PopCornnnn Aug 05 '22 at 10:16
  • In this specific case it is only done for performance reasons (the fields are final): it allows the Java JIT compiler to perform some more advanced optimizations at runtime. – Mark Rotteveel Aug 05 '22 at 10:17
  • Even if this does offer an advantage in performance. Most people wouldn't recommend doing it for just any code because the advantage is very small, and mostly non-existent depending on the context. – matt Aug 05 '22 at 10:18
  • https://stackoverflow.com/questions/20750020/java-which-is-faster-local-variables-or-accessing-encapsulation – matt Aug 05 '22 at 10:18
  • Yes, I agree with Matt, this is not something that you should do in normal code, unless you have verified it actually improves performance for your use case (or if it is even a bottleneck). – Mark Rotteveel Aug 05 '22 at 10:19
  • I see, thank you for answering. Is there any guide for me on going deeper in java? – PopCornnnn Aug 05 '22 at 10:23
  • @PopCornnnn Resource requests are off-topic on Stack Overflow, and to be honest, your question is rather non-specific, so it would be a bit hard to give a suggestion. – Mark Rotteveel Aug 05 '22 at 11:13

0 Answers0