Milchshakee
Milchshakee

Reputation: 23

What is the reason behind this weird implementation of System.console()?

I stumbled upon the source code of System.console() and I'm unsure why exactly it is implemented like this:

/**
 * Returns the unique {@link java.io.Console Console} object associated
 * with the current Java virtual machine, if any.
 *
 * @return  The system console, if any, otherwise {@code null}.
 *
 * @since   1.6
 */
 public static Console console() {
     Console c;
     if ((c = cons) == null) {
         synchronized (System.class) {
             if ((c = cons) == null) {
                 cons = c = SharedSecrets.getJavaIOAccess().console();
             }
         }
     }
     return c;
 }

More specifically, what is the point of the assignments to c? The variable cons is already static and holds the console object.

Upvotes: 2

Views: 92

Answers (1)

Konrad Rudolph
Konrad Rudolph

Reputation: 545875

tl;dr: It’s a common optimisation technique.

This pattern is called double-checked locking.

The implementation could also just look much simpler, as follows:

public static synchronized Console console() {
    if (cons == null) {
        cons = SharedSecrets.getJavaIOAccess().console();
    }
    return cons;
}

However, that way we would always lock the entire System class for every single call of the console method, which would lead to a substantial slowdown in typical applications.

Instead, the actual implementation defensively locks the object only if it can’t acquire a valid cons instance. And it assigns the result to a local variable c so that this instance remains valid even if another thread overrides cons after the (unlocked) check happens. It also helps reduce reading the cons reference, which is declared as volatile, and reading it is thus slower than reading a non-volatile reference.

Upvotes: 4

Related Questions