File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes threadsafety of a singleton Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "threadsafety of a singleton" Watch "threadsafety of a singleton" New topic
Author

threadsafety of a singleton

Robert Strong
Ranch Hand

Joined: Sep 10, 2002
Posts: 84
hi,

I'm a little confused about the role static initialization played in threadsafety of a Singleton class.

a Singleton class like below seems to be working correctly without making the reference variable final.

public class Singleton {
private static Singleton s = new Singleton();

public Static Singleton getInstance() {
return s;
}
}

however, I saw lots of singleton examples in Effective Java look like below, with a final keyword
public class Singleton {
private static final Singleton s = new Singleton();

I heard some people say that static initialization use internal synchronization of classloader to ensure no race condition for the reference variable? is it true?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

The "final" attribute has nothing to do with synchronization; it simply tells the compiler that no other code is allowed to assign a new value to that variable.

Clearly that's an important design consideration for a singleton object. But since the variable is private, only code in the Singleton class could do that, and you can inspect the code to see that isn't the case.

However, synchronization aside, that code has a much more serious flaw for something that claims to be a "Singleton": it doesn't prevent anybody else from creating their own Singleton object.
Dana DeVice
Greenhorn

Joined: Nov 24, 2008
Posts: 1
I think Paul is implying that you should declare a private constructor for your class so it cannot be instantiated outside of your class.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

D DeVice wrote:I think Paul is implying that you should declare a private constructor for your class so it cannot be instantiated outside of your class.


That's the usual solution that I have seen. There may be others for all I know, but since I don't need a singleton I haven't really followed the voluminous literature which has been produced about them.
Robert Strong
Ranch Hand

Joined: Sep 10, 2002
Posts: 84
yes, I do use private constructor.

but my question is that if the Singleton class is accessed by multiple threads, is it possible to have a race condition, that in the middle of static initialization, another thread calls getInstance() and thus return null? as no synchronization employed in getInstance() method to ensure timely visibility and atomicity.

Jim Hoglund
Ranch Hand

Joined: Jan 09, 2008
Posts: 525
If your singleton has no constructor you will access it statically, like:
MyClass.getInstance(). Loading MyClass kicks off the static code blocks
and other member inits. They are run in order, from top to bottom. This
would include initializing the object to be returned by getInstance(). So
there can be no race condition because building the object to be returned
will complete before the return occurs. Does this help?

Jim ... ...


BEE MBA PMP SCJP-6
Robert Strong
Ranch Hand

Joined: Sep 10, 2002
Posts: 84
Jim,

yes, that helps.

So, when the classloader thread start loading the Singleton class, it also kick off static initialization, which is guaranteed to happen before the class is used.
Chris Hurst
Ranch Hand

Joined: Oct 26, 2003
Posts: 407
    
    1

It's a really interesting question ;-)

The quick answer is final member initialisation does have special guarantees in the new Java Memory Model i.e. its not just about prohibiting reassignment in a multi threaded world, however it turns out the guarantees that static always provided are enough in this case ..


Ok so drilling into this in depth the question is ...
Have you prevented any data races and ensured visibility and with final static you have and the question is has the final achieved this for you.

Looking on the net there are a few goof confused blogs round this and I can see why.

final has special meaning under the new JMM (Java Memory Model) when used with member initialisation and multi threading, the question is it's visibility properties necessary given that its also declared static which also has some "interesting" properties with multi threading. Its important you pick up on the fact that final is not just about prohibiting new value assignment in a multi threaded world as if you use a non static final variable vs a non static final variable there is a obvious difference with multithreading.

See "How do final fields work under the new JMM? in the link below" ...
Java Memory Model

Next looking at static I can see where the confusion kicks in (the confusion would be round visibility not data races), there is indeed synchronization in the static initialisation of the class and always has been pre the JMM changes (so no data races) , you just need to confirm visibility, this you would assume given synchronisation is there but some documents don't make it clear e.g. Doug's JSR133 cookbook says ..

Static final initialization requires StoreStore barriers that are normally entailed in mechanics needed to obey Java class loading and initialization rules.


Which I first took to mean you need static final to get your memory barrier, however having looked at the java memory model documentation ...

The rules for class initialization ensure that any thread that reads a static field will be synchronized
with the static initialization of that class, which is the only place where static final fields can be
set. Thus, no special rules in the JMM are needed for static final fields.


So indeed in this particular case where multi threading is concerned final is giving you nothing, static is giving you already.


Again good question .

You might also want to look at ..
- How multiple class loaders can give you multiple singletons.
- How leaking the this reference or early access to final variables can cause issues with multithreading.


"Eagles may soar but weasels don't get sucked into jet engines" SCJP 1.6, SCWCD 1.4, SCJD 1.5,SCBCD 5
Gagan Sabharwal
Ranch Hand

Joined: Apr 23, 2006
Posts: 48
Hi Chris,

As per my nderstanding,

1) I think in context of thread safety final is used to make an object immutable.Also since final in new JMM has a changed meaning which says that if the variables of a class are final, then during the instantiation, all those varibles will get properly initialized value before the reference of that instance is made visible to other threads.

2) The internal Data Structure(which contains the constant pool) in the runtime area is thread safe, which is used by the classloader to load the class and create a .class instance. Now since Static initialization happens just after the class is loaded by the class loader and its .class instance is created in the heap, it remains questionable whether the assignment of appropriate values to static variables is thread safe or not.

Could someone throw some light on the same ?
Chris Hurst
Ranch Hand

Joined: Oct 26, 2003
Posts: 407
    
    1

I think in context of thread safety final is used to make an object immutable.


No, not really ..
First final doesn't make an object immutable, it makes its reference immutable, unless you mean make it immutable and then make any members similarly final. Java final isn't the same as C++ const and immutable is a dangerous word in multithreading, as an example String was always immutable but early java versions experienced an issue where they were not thread immutable i.e. they were immutable to any public interface but that does not mean thread immutable privately they mutated which was an issue.

Also since final in new JMM has a changed meaning which says that if the variables of a class are final, then during the instantiation, all those variables will get properly initialized value before the reference of that instance is made visible to other threads.


No.
First they will have been initialised but the result of any assignment may not be visible to any thread i.e. another thread may perceive them as if the actions of the first thread have not happened. Consider a class with non static member as part of the "no values out of thin air guarantee" this value is initialised to zero and then assigned to 6 , any subsequent assignment is prohibited. This assignment is guaranteed (new guarantee) to be visible to another thread when the constructor has completed, before that myconst could be observed to be zero by another thread . Think of it as the write of 6 may be cached which has to be released to main memory then the reading thread must invalidate its cache and pull the new value from memory if it helps. There is a visibility issue which is like an inability to guarantee invalidation of caches in this scenario (caches is not the only reason this can happen so strictly speaking we should talk in terms of "happens before ordering").

I suggest reading "Java Concurrency in Practice" for a better explanation, its a very hard topic to get explain with out dropping into formal language.

2) The internal Data Structure(which contains the constant pool) in the runtime area is thread safe, which is used by the classloader to load the class and create a .class instance. Now since Static initialization happens just after the class is loaded by the class loader and its .class instance is created in the heap, it remains questionable whether the assignment of appropriate values to static variables is thread safe or not.


The Java memory model says ...

The rules for class initialization ensure that any thread that reads a static field will be synchronized
with the static initialization of that class, which is the only place where static final fields can be
set. Thus, no special rules in the JMM are needed for static final fields.


We're discussing static final and there is no debate unless you believe I have not fully understood the quote from the Java Memory Model, any modern JVM that did not exhibit this behaviour as written would be bugged.

If you feel I may be miss interpreting some of your arguments I suggest you post this on the Java memory model discussion list where some of the guys behind the JMM subscribe , I'm always learning new stuff off there, though it is a bit techie.



 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: threadsafety of a singleton
 
Similar Threads
Generic Singleton Class
Servlets Netbeans ThreadSafety Easy Question.
threadsafety in JSP
ThreadSafety of HttpServletRequest & HttpServletResponse objects
B&S: Threadsafety & RandomAccessFile