0

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.

Community
  • 1
  • 1
xst
  • 2,536
  • 5
  • 29
  • 41

4 Answers4

2

Lazy initialization, i.e. delay the work until it's really necessary.

Wormbo
  • 4,978
  • 2
  • 21
  • 41
  • but why not then just lazily initialize the member field? – xst Feb 02 '13 at 21:04
  • The method encapsulates exactly that. It is used to get the value of the field and ensures it's initialized when needed. – Wormbo Feb 02 '13 at 21:06
  • `if (linePattern == null) linePattern = new ...` This would lazily initialize the member field instead of the local variable. – xst Feb 02 '13 at 21:26
1

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

Grzegorz
  • 504
  • 1
  • 3
  • 14
1

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

Cratylus
  • 52,998
  • 69
  • 209
  • 339
0

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.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • the volatile keyword guarantees that reads do not overlap, as is stated in the reference (that I just added). Are you referring to volatile in C, where it's used to read memory-mapped IO devices? – xst Feb 02 '13 at 21:25
  • No, I'm very definitely referring to volatile in Java. The reference you've stated means that `linePattern` won't overlap in the middle of one specific read or one specific write, but if you're doing multiple reads and/or multiple writes, the value can be changed by other threads in between those operations. – Louis Wasserman Feb 02 '13 at 22:27