Win a copy of Design for the Mind this week in the Design forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

can't understand this program...

 
Nikhil Pujari
Greenhorn
Posts: 21
C++ Firefox Browser Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am new to threads, and I must say I have never spent more time understanding any other topic for the SCJP than this. Anyway, I wrote this simple threads program and I can't understand how the result was arrived at. Program and result are shown below.

Program:



result:



My question is regarding lines 7 and 9.There seems to be a jump in the value of "i" from 3 to 5, without first going thru 4, which shows up later. How can this be possible?
 
Alexander Kober
Ranch Hand
Posts: 32
IntelliJ IDE Java Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Standard race condition:

+ T0 and T1 both enter the for loop and execute #8.
+ T0 executes the (++i) in #9 and increments the shared variable.
+ T1 executes the (++i) in #9 as well as the println(...)
+ T0 executes the println(...) in #9.

All you have to keep in mind here is that expressions are evaluated from inside to outside. println(++i) is executed as 1. (++i); 2. println(...);

It is very important to know what operations are executed atomically (as in: This statement executes fully or it doesn't, but there are no intermediate states). By that definition, and this is a common pitfall for people new to threading, (i++) is not atomic either, as it is a shorthand for 1. get i, 2. increment what you got, 3. write the result to i.
 
Henry Wong
author
Marshal
Pie
Posts: 21003
76
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To add to that, one of the reasons that this printout is somewhat (relatively) stable, is because the program is doing I/O. The I/O is causing the threads to flush it registers (along with adding time between the portions of code which access the unsafe variable).

If I/O was not done, meaning the loops were doing lots of iterations, there will not only be more "skips" (or "jumps"), but there will also be cases where the value seems to go "backwards". Of course, you won't be able to see it without the I/O printouts -- sort of a case of Schrodinger's Cat ...

Henry
 
Nikhil Pujari
Greenhorn
Posts: 21
C++ Firefox Browser Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a ton. The thought that println may not be an atomic operation did cross my mind, but I wasn't sure. Thanks again.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nikhil Pujari wrote:The thought that println may not be an atomic operation did cross my mind, but I wasn't sure. Thanks again.


No method call is ever atomic. About the only things that are atomic are reading from and writing to variables, except that reading/writing longs and doubles is not atomic if the variables in question are not declared volatile. Of course, we can make any chunk of code behave as if it were atomic with the proper use of synchronization or the higher level constructs in java.util.concurrent.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic