Question about concurrency and safe publication...
Julien Martin
Ranch Hand
Joined: Apr 24, 2004
Posts: 383
posted
0
Hello,
I am in reference to Java Concurrency in Practice by Brian Goetz and the following code snippet from page 51.
I read from the aforementioned book that the assertSanity method can throw an AssertionError as a result of unsafe publication of an Holder object. I am having trouble understanding how n can be different from itself as a result of unsafe publication.
You posted this same question in the Sun concurrency forum.
Well spotted! I am sorry if this violates the netiquette. I really thought one could post the same question on several forums....
omi sharma
Ranch Hand
Joined: Mar 18, 2008
Posts: 489
posted
0
I guessed ,Sun forum is different than Java-ranch's. So there has been no conflict.
best regards, omi
SCJP, OCA 9i application developer, SCWCD 5.
When I was in hell someone told me to get heaven you need to do Java.
Ulf Dittmer
Marshal
Joined: Mar 22, 2005
Posts: 35249
7
posted
0
You're certainly free to post in both places, but in that case we'd like you to BeForthrightWhenCrossPostingToOtherSites, as would the folks over at the other forums. It's the polite thing to do.
If this is not an atomic operation, it can result in 'true' if multiple threads change the value of 'n'
Thanks and Regards
Ulf Dittmer
Marshal
Joined: Mar 22, 2005
Posts: 35249
7
posted
0
Originally posted by Satya Maheshwari:
If this is not an atomic operation, it can result in 'true' if multiple threads change the value of 'n'
It's indeed not an atomic operation, but the class has no setters, so the value can't be changed. The secret to the problem here is in unsafe publication of the object, and to understand that one has to understand the so-called memory model of Java.
I have read that book, and wholeheartedly recommend it to every Java developer. There's much to know about concurrency in Java -a topic that gets more important by the year, what with multithreaded processors and multicore processors-, and this book teaches it all, including all the stuff that got introduced in Java 5. [ August 15, 2008: Message edited by: Ulf Dittmer ]
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2782
2
posted
0
[Ulf]: It's indeed not an atomic operation, but the class has no setters, so the value can't be changed.
Well, the value does change within the constructor. The field n is zero at the beginning of the constructor, and set to some other value by the end. So if one thread create a Holder and immediately passes the reference to another thread which calls assertSanity(), it's possible for the second thread to see an error.
Julien Martin
Ranch Hand
Joined: Apr 24, 2004
Posts: 383
posted
0
Thanks all for your input!!
Satya Maheshwari
Ranch Hand
Joined: Jan 01, 2007
Posts: 368
posted
0
So if one thread create a Holder and immediately passes the reference to another thread
Could you please elaborate a bit more on this? Did you mean that another thread calls assertSanity() on an instance of 'Holder' while the original thread is still in the process of 'constructing' this instance and hence n!=n may turn out to be true. But that does not sound possible how could we call an instance method before the instance has still in the process of being created. I am confused here
Could you please elaborate a bit more on this? Did you mean that another thread calls assertSanity() on an instance of 'Holder' while the original thread is still in the process of 'constructing' this instance and hence n!=n may turn out to be true. But that does not sound possible how could we call an instance method before the instance has still in the process of being created. I am confused here
When the constructor lets the "this" reference escape. Have a look at this article for more info.
Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
Satya Maheshwari
Ranch Hand
Joined: Jan 01, 2007
Posts: 368
posted
0
When the constructor lets the "this" reference escape.
Yes I agree. Thanks for pointing this out.
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2782
2
posted
0
If the constructor lets a "this" reference escape, that's a problem, true. However that doesn't happen in the Holder code above - and yet it's still possible for assertSanity() to fail.
[Satya]: Could you please elaborate a bit more on this? Did you mean that another thread calls assertSanity() on an instance of 'Holder' while the original thread is still in the process of 'constructing' this instance and hence n!=n may turn out to be true. But that does not sound possible how could we call an instance method before the instance has still in the process of being created. I am confused here
Well, this is one of many weird reordering effects that can occur when using multiple threads if you don't make proper use of thread-safety techniques like locking or using final. You could have code like this:
Here it certainly looks like new Holder() constructor will complete before assertSanity() is run. Unfortunately, that's not really guaranteed here. The processor can reorder some instructions in ways that do not affect the result of a single thread, but may be extremely counterintuitive when you work with multiple threads. Also some threads may be operating on cached data, and so changes made by one thread may not have been written to main memory yet, or other threads may not have read the data from main memory yet. In other words, with multiple threads, Weird Stuff Happens. Using final variables is one way to protect yourself from this sort of thing.