The moose likes Threads and Synchronization and the fly likes do not publish partially initialized objects? Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Reply Bookmark "do not publish partially initialized objects?" Watch "do not publish partially initialized objects?" New topic
Author

do not publish partially initialized objects?

Tapio Niemela
Ranch Hand

Joined: Jan 06, 2006
Posts: 69
Hi,

Brian Goetz warns about "publishing partially initialized objects" in his book "Java Concurrency in practice" (pages 49-54)

there's two java examples


Brian Goetz mentions about "because synchronization was not used to make the Holder visible to other threads, we say the Holder was not properly published". I'm terribly confused here. Is it because reference to Holder is stored to public field (and any thread could get reference to that, whatever it's state)? Or, if I have understood correctly java memory model doesn't guarantee that when retrieving object reference it's constructor has actually finished? This topic is also considered in https://www.securecoding.cert.org/confluence/display/java/TSM03-J.+Do+not+publish+partially+initialized+objects

If it's the latter it's very scary. That would mean that most of the java programs out there have threading issues..Also if that's the case, how would instance variables constructed at "class" level behave? I mean following situation..

Nomaan Butt
Ranch Hand

Joined: Oct 19, 2011
Posts: 54
Is it because reference to Holder is stored to public field (and any thread could get reference to that, whatever it's state)?




As the reference is public so any thread can get it, whatever its state may be.

Or, if I have understood correctly java memory model doesn't guarantee that when retrieving object reference it's constructor has actually finished?


Consider an example



In th above code reference 'a' is set to this reference before 'n' is initalized and as 'a' is public therefore any thread can access it any time.
Suppose thread1 is creating an object of class A and before 'n' is initialized ie just after the execution of below statement
thread2 accesses public reference 'a' then it will refer the partially initialized object with n having the default value.


Tapio Niemela
Ranch Hand

Joined: Jan 06, 2006
Posts: 69
Thank you Nomaan Butt

I think I finally figured this out after I posted the topic, your reply assures my assumption..

I was so confused about that "when object is constructed Object constructor is run and all member variables are set to their default values, thus Holder could have 'stale' member variable values " which is also mentioned in the book. But now it makes sense. It's all about the public reference and threads interfering with each other..
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2127
No, there actually was also something very important here:
Tapio Niemela wrote:Or, if I have understood correctly java memory model doesn't guarantee that when retrieving object reference it's constructor has actually finished?

Indeed, the Java memory model does not make such a guarantee - at least not for the code shown. It makes such a guarantee for final fields, but not for nonfinal fields. Even if those nonfinal fields are never intentionally changed after the constructor completes. If you want to use nonfinal fields in a thread-safe manner, there needs to be some synchronization* involved before the reference is published (i.e. before it's written to a public static field, for example). Otherwise weird, counterintuitive things can happen in the JVM.

* In Goetz' book the term "synchronization" is used in a general way to include using the synchronized keyword, the volatile keyword, atomic and locking classes from the java.util.concurrent packages, and possibly a few other mechanisms I've forgotten. So it doesn't necessarily imply you need the synchronized keyword, but something along those lines.
Tapio Niemela
Ranch Hand

Joined: Jan 06, 2006
Posts: 69
Thanks for reply Mike,

Yes, I understand also what you are saying, but the case with the Holder example isn't just with final fields. (Although it can be fixed by declaring holder to be final, or field 'n' of the Holder class final). It was bit unclear what Goetz ment..

This is what I have understood. Please correct me if I have misunderstood..



Now without synchronization this could happen
1. Thread a constructs new Holder by calling HolderHolder.initialize. First, constructor of Object class is called. This will set the n to 0, after that Holder constructor sets it to 42.
2. Meanwhile thread b constructs also new Holder, but with same reference. It will also call Object constructor and set fields to default values
3. Now thread a starts assertSanity method
4. n is now 0 (set by thread b)
5. thread a reads n value (which is 0)
6. thread b continues with Holder constructor, setting n to 42
7. thread a reads n value again, which is now 42

Also I don't think that simply declaring holder to be volatile would be sufficient, because it is never checked if the holder is constructed (not null). Instead some sort of double-checked locking should be used. Am I wrong?

Thanks for the patience
Nomaan Butt
Ranch Hand

Joined: Oct 19, 2011
Posts: 54
In the above code you are creating two different thread objects, each Test thread has separate HolderHolder object and separate Holder object and therefore separate integer field 'n'. Therefore none will interfere.
If 'n' is static then only there can be interference, volatile will also not have any effect here as objects are different.
 
IntelliJ Java IDE
 
subject: do not publish partially initialized objects?
 
Threads others viewed
Initialize-On-Demand idiom vs simple static initializer in Singleton implementation
How a method on stack knows that to which object on heap it is connected?
Question about concurrency and safe publication...
How is this a safe publication?
Using "this" keyword in parent class thread safe?
IntelliJ Java IDE