1

about static initialzers which are threadsafe and carried out by a single thread at class load time, why should I use a "private final static field" in the singleton if a "private static field" makes to my understanding the same threadsafe and visibility guarantees - provided that the static field will not be touched after the static initialization.

Simply, I do say the following two examples below are behaving identical in a multithreaded environment: Any time any client will get returned the same instance - there is not even the faintest difference - do you agree ? Please let me know in either way.

Example static field:

public class Singleton {

    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }

    private Singleton() {
    }
}

Example final static field:

public class Singleton_final {

    private final static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }

    private Singleton() {
    }
}

Kind regards, Hermann

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
user2050516
  • 760
  • 2
  • 5
  • 15

2 Answers2

1

In the case of the code you've given, no there is no difference, because you have no method of actually setting a new instance of the Singleton class because you don't have any constructors, or setters viewable outside the class.

However that isn't to say that without the final that the Singleton instance could be changed. The Reflection API could theoretically be used to change the instance, if you didn't have the final qualifier. I say theoretically because I've never tried it myself, and I can't think of a way off the top of my head. I yield to anyone with a little more experience with the Reflection API

JamesENL
  • 6,400
  • 6
  • 39
  • 64
1

As with many multithreading issues, it's a bit subtle. Allow me to dig into the question a bit, and then provide a kinda-answer.

Refining the question

If a client sees a non-null reference, they'll only ever see the one Singleton you create. Of that there's no question. Here are the two questions:

  • is it possible for anyone to see null?
  • is it possible for someone to see a partially constructed Singleton?

The latter question isn't quite relevant to your case, because the Singleton doesn't have any state. But if it did have state, and that state was stored in non-final fields, then it would be an issue. For instance, given:

public class Singleton {
    private /* non-final */ String name;

    private Singleton(String name) {
        this.name = name;
    }
}

... a partially-constructed Singleton is one whose name is null (despite having been set to a non-null value at construction time).

What you would want is probably (a) that nobody sees null and (b) that nobody sees a partially-constructed object. To get that, you need the class to be free of data races. To do that, you need a happens-before relationship.

So the question is really: is there a happens-before relationship between the thread that initializes instance, and any thread that later reads it?

So, what's the answer?

The JLS is a bit iffy on this. There's a detailed description of class initialization at JLS 12.4.2 which includes locking on the class, and thus introduces a happens-before edge. But there's nothing in the JLS to specify what happens when a class is already initialized! In those cases, the JLS doesn't require any lock, and therefore doesn't establish any happens-before relationship. A strict reading of the JLS would suggest that clients in other threads could see a null reference or partially-constructed object.

The JLS hints that this shouldn't happen in 12.4.1:

The intent is that a class or interface type has a set of initializers that put it in a consistent state, and that this state is the first state that is observed by other classes.

Well, that's great that this is "the intent," but there's nothing (other than that statement of intent) to require it.

A final field (static or not) gets special thread safety semantics (JLS 17.5, or see this question on SO) that essentially provides the aforementioned happens-before edge, and thus removes the data race and ensures a non-null reference to a fully-constructed object.

Community
  • 1
  • 1
yshavit
  • 42,327
  • 7
  • 87
  • 124
  • so what you basically say final has special thread safety semantics and you can be certain from your standpoint. – user2050516 May 30 '14 at 08:31
  • `final` definitely has special thread safety semantics. The question is whether they're actually needed in this instance, and that's what the JVM is a bit confused about. :) – yshavit May 30 '14 at 16:14