Java Lock variable assignment before use. Why?

前端 未结 5 1665
迷失自我
迷失自我 2020-12-06 07:11

In a lot of of the Java source, (for example LinkedBlockingDeque) I see things like this;

final ReentrantLock lock = new ReentrantLock();

publi         


        
5条回答
  •  鱼传尺愫
    2020-12-06 07:48

    Digging in the code a little bit I have found examples for both ways by the same author, Doug Lea:

    • LinkedBlockingDeque (since JDK 1.6) uses the "direct access" method.
    • CopyOnWriteArrayList (since JDK 1.5) uses the "local variable" method.

    There are more examples for each idiom in java.util.concurrent but it seems, that for each class a consistent style has been chosen.

    Please note, that in all relevant cases the lock field has been declared final. That is the most important part, because the memory model semantics for final fields are a bit special in JVM (see JLS).

    Building on that: Taking a local copy or not does not affect multithreading correctness.

    Also note that Dough Lea has chosen the shorter style in newer code (as shown in the examples). So perhaps the "take a local copy" idiom is some leftover from the days before java.util.concurrent has been part of the JDK and before the JVM memory model has been adopted appropriately. I speculate that the code before that adoption might have looked like this:

    public void op(){
        ReentrantLock lock = getLock();
        lock.lock();
        try {
            realOp();
        } finally {
            lock.unlock();
        }
    }
    

    where getLock() did contain some crude multithreading safe logic.

提交回复
热议问题