I have been trying to study the synchronized portion of java certification exam, and I have this code (is a changed version of Mughal book question 13.13), but I can't explain it.
My understanding is that since incrementing k1 and k2 is synchronized, they should always be equal, and I should never see the print statement. But when I run the code I get the print statement anyway! (and even sometimes it shows that k1 and k2 having the same value (eg. k1: 200931 k2: 200931), but I can postpone worrying about that for a later time).
What am I missing? (Did I at least get this part correct that since k1 and k2 are static, then I need a static lock (Q13_13.class))?
Here's what's happening when you see the printout (or one possible sequence, anyway):
- Thread A goes into the synchronized block and increments k1 and k2. Thread B is blocked (because both threads are synchronizing on the same object)
- Thread A leaves the synchronized block.
- Before A reaches the if statement, Thread B enters the synchronized block, and increments k1.
- Thread A regains control before Thread B increments k2. It checks the if statement, which is true.
Then, sometimes, Thread B manages to increment k2 after A has checked the if statement, but before it prints out the values. That's why they sometimes appear to be the same.
The key point is that only the synchronized block is protected. As long as one thread isn't blocked, there's the possibility of control passing between them at any time.
Joined: Nov 04, 2009
Nice! So now I understand that k1 can become greater than k2 in that case. But it seems like k2 can also become greater than k1, and I don't know how to explain it, and the difference between k1 and k2 is not just by one. (I changed line 15 to if(k1 < k2) and I still get the print statement. eg. k1: 365731 k2: 365898)