JMM: Constructors don’t have visiblity/reordering problems

April 2, 2008

One of the things that has been bugging me for some time is this: do I need to prevent visibility/reordering problems inside my constructor. With normal methods it is quite clear if there are visibility problems, eg:

class Foo{

	int a=0

	void init(){
		a=1;
	} 

	void print(){
		println("a="+a);
	}
}

If the init method is called by some thread, others threads don’t need to see the newest value of a (ever). This problem can easily be prevented by making a volatile or doing read/write of a inside a synchronized block(there are more ways). But constructors are a different story, because the reference to the newly created Foo instance, needs to be published safely before other threads are able to read fields of that instance.

class Foo{
	int a;

	Foo(){
		a=1;
	}

	void print(){
		println("a="+a);
	}
}

//safe publication
volatile Foo foo = new Foo();

This safe publication acts as the missing link to make ‘piggybacking on synchronization’ possible; so even though the newly created object(s) still has visibility/reordering problems, after the safe publication has been executed, all other threads will see a correctly constructed object when they read foo. It is very important to realise this will only work with a safe publication, otherwise there will be problems.

So from a technical point of view there are no issues. The question is if this is a correct way to deal with this situation. Personally I prefer to remove all jmm issues inside the constructor (in 99% of the cases by making the fields final) so it removes any doubt how this class is going to behave regarding jmm. When I inspect code being used by multiple threads, one of the first things I look at are the fields and the constructors. If there are jmm ‘problems’ inside the constructor, it is likely that others methods have problems as well.

ps:
Last year I wrote a blogpost about the Spring container providing a safe publication, you can check it here.