JMM: Constructors don’t have visiblity/reordering problems

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.

About these ads

14 Responses to JMM: Constructors don’t have visiblity/reordering problems

  1. kodeninja says:

    If making fields final is not an option, what can be done to prevent this situation?

  2. miluch says:

    Hi Peter,

    I found this entry by following link at the comment you made on http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/.
    I know that this post (and the one you commented as well) is quite old but i hope you can help me understand “safe publication idiom” from JCIP.
    For brevity i will reference code of SomeClass from http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/. From JCIP point of view SomeClass is immutable so it can be safely published through any mechanism ( section 3.5.5 of http://codeidol.com/java/java-concurrency/Sharing-Objects/Safe-Publication/). Is it correct ?

    I just do not believe that if i store an instance of SomeClass in private field of some other object any other thread could see that instance. So why Goetz in his book write about “any mechanism to publish immutable objects”?
    It just does not make sense to me…

    • pveentjer says:

      Hi Miluch, I’ll have a look at it this evening.

    • pveentjer says:

      From JCIP point of view SomeClass is immutable so it can be safely published through any mechanism ( section 3.5.5 of http://codeidol.com/java/java-concurrency/Sharing-Objects/Safe-Publication/). Is it correct ?

      That is correct

      I just do not believe that if i store an instance of SomeClass in private field of some other object any other thread could see that instance.

      This is a different story. Although the some class itself can be used safely in a multithreaded environment, it doesn’t mean that an object that refers to this automatically becomes thread safe.

      E.g.

      Class AnotherClass{
      Private SomeClass instance;

      Public void set(SomeClass instance){this.instance=instance;}

      Public SomeInstance get(){return instance;}
      }

      In this case the access to the instance is not threadsafe, even though SomeClass is threadsafe. A practical consequence could be that a thread doesnt need to see the most recent written value (ever). Even the jit could complicates matters by eliminating the get or set if it doesnt matter for the thread that uses the get or set.

      Does this answer your question?

      So why Goetz in his book write about “any mechanism to publish immutable objects”? It just does not make sense to me…

      It only holds for the immutable object itself but doesnt say anything about a surrounding datastructure that is not threadsafe

  3. miluch says:

    Hi

    After a thorough reading of a few parts from JCIP ( chapter 3 and section 16.2 till the end of chapter) and your comment i am still stuck on it.
    The most vague parts are “Immutable objects can be published through any mechanism” from JCIP and the whole buzz story about final fields…
    For me, final fields are from concurrency point of view useless. I do understand that if thread T2 grab reference to an object A that has been properly constructed by thread T1, then all values of final fields of A are seen by T2 in as-constructed state. It is called initialization safety.
    That’s all fine but how to make a reference to A visible to thread 2 ?
    IMHO you need to use synchronization (volatile reference, lock, AtomicReference). But if you employ any from of the synchronization, ‘piggybacking on synchronization’ will make everything visible to Thread2, no matter if fields of object A are final or not! So why use final fields ?

    What is the meaning of “immutable objects can be published through any mechanism” ?

    Goetz in his comment(
    http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/comment-page-1/#comment-113671) wrote that your reasoning is correct IF instance of SomeClass is itself safely published.Since SomeClass is immutable then according to “immutable objects can be published through any mechanism” it does not need to be safely published…

    • pveentjer says:

      For me, final fields are from concurrency point of view useless

      This is not correct. What the final essentially does is to provide a mechanism (if properly used) that the object itself is created in a safe way, whatever outside is doing.

      I do understand that if thread T2 grab reference to an object A that has been properly constructed by thread T1, then all values of final fields of A are seen by T2 in as-constructed state. It is called initialization safety.

      For the exact semantics I would read java concurrency in practice. But all fields that are written before a reference to a final field in the constructor is used, will be just as visible as if they where final.

      So:

      class Foo{
          int foo;
          final int bar;
      
          Foo(){
             foo = 10;
             bar = 100;
          }
      }
      

      Is just as correct as:

      class Foo{
          final int foo;
          final int bar;
      
          Foo(){
             foo = 10;
             bar = 100;
          }
      }
      

      That’s all fine but how to make a reference to A visible to thread 2 ?
      IMHO you need to use synchronization (volatile reference, lock, AtomicReference). But if you employ any from of the synchronization, ‘piggybacking on synchronization’ will make everything visible to Thread2, no matter if fields of object A are final or not! So why use final fields ?

      That is correct. That is exactly what this blogpost describes :)

      What is the meaning of “immutable objects can be published through any mechanism” ?

      In this case the word ‘immutable’ means ‘safely constructed immutable object’. So one with at least one final field that is accessed in the end. The big difference with a normal ‘immutable’ object is that the former relies on the outside environment for safe publication and with a ‘safely constructed immutable object’ they outside can’t screw up this object itself, although the the reference to the immutable object still could be screwed up. You could see it as a safety line.

      If the reference isn’t published safely it still could be that another thread sees some stale value of the reference or could even run in more damaging inconsistencies if there is a more complex unsafe data-structure is referring to the ‘safely created immutable object’.

  4. miluch says:

    So for a moment let’s assume we do not care about how to make a reference to an object visible to other thread.
    Object A is immutable ( has final fields) so we can be sure that no matter how we publish A (can store it in public field) we can be sure that other thread will see A in its correct state – it is not possible that other thread will see A in partially constructed state.

    If A is ‘effectively immutable’ (is not mutable but fields are not final) it is possible that other thread sees A in partially constructed state.
    Am i right ?

    • miluch says:

      Sorry it should be:

      Object A is immutable ( has final fields) so we can be sure that no matter how we publish A (can store it in public field) we can be sure that IF other thread sees reference to it will see A in its correct state – it is not possible that other thread will see A in partially constructed state.

      If A is ‘effectively immutable’ (is not mutable but fields are not final) it is possible that IF other thread sees reference to A it can see A in a partially constructed state.

      • pveentjer says:

        Yes.. that is correct.

        A few of the things that can happen are:

        - storing the value in an object field can be reordered with the actual constructor code, so an observing thread could see a partially constructed object.

        - it could be that some values written by the constructor are not visible yet in the other cache. So another reason why a a thread could observe a partially constructed object.

        So if you publish safely your not safely constructed immutable object, or publish not safely your safely created immutable object, everything will be fine (of course it will also be fine of the safely constructed object is published safely).

  5. miluch says:

    I do understand all the hazards as presented in your comment.
    By safely constructed object you mean an object with final fields ?
    By safe publication you mean using synchronization to publish reference to the object so it can be seen by other thread ?

    What do you mean by publishing not safety?

    • pveentjer says:

      By safely constructed object you mean an object with final fields ?

      Yes

      By safe publication you mean using synchronization to publish reference to the object so it can be seen by other thread ?

      Yes… using synchronized or volatile/atomic variable for example.

      What do you mean by publishing not safety?

      Through a normal field.

  6. miluch says:

    IMHO all reference publications ( because of problems with reference visibility to other thread) must be safe.

    Can you point me to at least one “real world” scenario you would use unsafe publication?

    • Peter says:

      I don’t think that in most normal applications it has a valid use-case. Only if you want to get the most out of performance and you are really experienced with concurrency, you are able to deal with relaxed consistency.

  7. miluch says:

    Hi

    I do not know why google forgot to notify me about your last reply in 2010 but received it a few minutes ago. So I read through our conversation and i think i finally managed to understand this stuff.
    To summarize, use safe publication and use final fields (safely constructed objects) as safety net.
    Anyway thx for your time and patience

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: