简体   繁体   中英

Local variable used to access volatile instance variable

What is the purpose or value of creating a local reference to a static volatile variable that is already kept as a member field. This code here is from java.util.Scanner JDK 6b14 here .

class Scanner {
    private static volatile Pattern linePattern;
    ...
    private static Pattern linePattern() {
        Pattern lp = linePattern;
        if (lp == null)
            linePattern = lp = Pattern.compile("...");
        return lp;
    }
    ...
}

The Java Tutorials : "Reads and writes are atomic for all variables declared volatile (including long and double variables)... any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. "

This means that reading the reference to the Pattern object won't fail half-way because it has changed. The volatile keyword is supposed to protect exactly these kinds of accesses, so I don't the duplicating local variable is meant to ensure that a valid value is returned.

Also, the lazy initialization can be done on the member field without needing an intermediary local variable:

if (linePattern == null) linePattern = Pattern.compile("...");

It looks to be a byte-code optimization as seen here and here . Using local variables produces smaller bytecode (less instructions) as well as less accesses to the actual value (which is an expensive volatile read). However they have not used the final variable optimization along with it, so I'm skeptical about drawing this conclusion.

延迟初始化 ,即将工作延迟到真正需要的时候。

It guarantees that returned value is not NULL - even if the static variable is set to NULL between check and return.

And at the same time it is an unsynchronized lazy init with re-initialization if needed ;).

This "speed" up things. Access to volatile variables is expensive. Use can get away with this overhead by assign it to a stack variable and access that instead

For volatile fields, the linePattern might change in between different lines. Copying the reference to a local variable makes certain that you can't have an inconsistent state. For example, if you had written

 if (linePattern == null)
    linePattern = Pattern.compile("...");

then linePattern might have stopped being null while the Pattern.compile was executing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM