Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Question about concurrency and safe publication...  RSS feed

 
Julien Martin
Ranch Hand
Posts: 384
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.

Can anyone please comment.

Thanks in advance,

Julien.
 
Edward Harned
Ranch Hand
Posts: 291
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You posted this same question in the Sun concurrency forum.

Try posting questions about the book on the author's blog.
 
Julien Martin
Ranch Hand
Posts: 384
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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....
 
Bobby Sharma
Ranch Hand
Posts: 598
3
Google App Engine jQuery Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I guessed ,Sun forum is different than Java-ranch's.
So there has been no conflict.

best regards,
omi
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Satya Maheshwari
Ranch Hand
Posts: 368
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


If this is not an atomic operation, it can result in 'true' if multiple threads change the value of 'n'
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[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
Posts: 384
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks all for your input!!
 
Satya Maheshwari
Ranch Hand
Posts: 368
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
Jelle Klap
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Satya Maheshwari:


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.
 
Satya Maheshwari
Ranch Hand
Posts: 368
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When the constructor lets the "this" reference escape.


Yes I agree. Thanks for pointing this out.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!