Does static provide additional guaranties in JMM context?

171 views Asked by At

I am reading about java singleton and I've met strange things.

I will refer to following artice as example(you can easy find more)

Author provides the following singleton:

public class ASingleton {

    private static ASingleton instance = new ASingleton();

    private ASingleton() {
    }

    public static ASingleton getInstance() {            
        return instance;
    }

}

and comments:

Pros:
-Thread safety without synchronization
- Easy to implement

Cons:
- Early creation of resource that might not be used in the application.
-The client application can’t pass any argument, so we can’t reuse it.
For example, having a generic singleton class for database connection
where client application supplies database server properties.

I want to get clarification about Thread safety without synchronization point.

I've read concurrency in practice book and don't remember anything related with this.

I missed something or this clarification is not relevant?

Additionally I want to tell you that you can encounter the same singleton but field marked as static final instead of just static
P.S.

I understand that I can read JMM and this one contains the answer but I am usual guy and I can't undertand this source.

2

There are 2 answers

3
GhostCat On

According to securecoding.cert.org this is a valid pattern:

Variables that are declared static and initialized at declaration or from a static initializer are guaranteed to be fully constructed before being made visible to other threads. However, this solution forgoes the benefits of lazy initialization.

The point is: loading classes is a well defined operation. And executing static initializing code falls into the same category.

It is important to understand: JMM knowledge is only "required" when you go for the static field + lazy init variant:

Initialization of the static helper field is deferred until the getInstance() method is called. The necessary happens-before relationships are created by the combination of the class loader's actions loading and initializing the Holder instance and the guarantees provided by the Java memory model (JMM). This idiom is a better choice than the double-checked locking idiom for lazily initializing static fields [Bloch 2008]. However, this idiom cannot be used to lazily initialize instance fields [Bloch 2001].

Finally: the final keyword should not affect this at all. Using final is much more about expressing your intent to declare a well, final thing - instead of one that gets potentially updated later on.

4
Stephen C On

That idiom is sound with respect to the JMM.

There is a happens before relationship between the static initialization of a class and the use of any static variables. This is a consequence of the locking that occurs during the initailization procedure described in JLS 12.4.2.


According to my reading, instance does not need to be declared as final here to get the required happens-before. It is advisable for other reasons though.