wood burning stoves 2.0*
The moose likes Threads and Synchronization and the fly likes do not publish partially initialized objects? 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 "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: 77
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: 77
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: 3003
    
    9
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: 77
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.
ramesh vanka
Greenhorn

Joined: Mar 13, 2005
Posts: 11
This example comes under "A reference to the object containing the final field did not escape the constructor"

When you instantiate a new Holder object with the new operator,
1) the Java virtual machine first will allocate (at least) enough space on the heap to hold all the instance variables declared in Holder and its superclasses.
2) Second, the virtual machine will initialize all the instance variables to their default initial values.
3) Third, the virtual machine will invoke the <init> method in the Holder class.

please refer for above: http://www.artima.com/designtechniques/initializationP.html

Assume: 1st Thread starts 10:00 am, it calls instatied the Holder object by making the call of new Holer(42),
1) the Java virtual machine first will allocate (at least) enough space on the heap to hold all the instance variables declared in Holder and its superclasses. -- it will 10:01 time
2) Second, the virtual machine will initialize all the instance variables to their default initial values -- it will start 10:02 time
3) Third, the virtual machine will invoke the <init> method in the Holder class.-- it will start 10:04 time

Now Thread2 started at --> 10:02:01 time, and it will make a call assertSanity() 10:03, by that time n was initialized with default of Zero, Second thread reading the stale data.

//unsafe publication
public Holder holder;

if you make the public final Holder holder will resolve this issue

or

private int n; if you make the private final int n; will resole this issue.

please refer : http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html under section of How do final fields work under the new JMM?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: do not publish partially initialized objects?
 
Similar Threads
How is this a safe publication?
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...
Using "this" keyword in parent class thread safe?