From page 291 of OCP Java SE 6 Programmer Practice Exams, question 25:
public class Stone implements Runnable {
static int id = 1;
public void run() {
id = 1 - id;
if (id == 0)
pick();
else
release();
}
private static synchronized void pick() {
System.out.print("P ");
System.out.print("Q ");
}
private synchronized void release() {
System.out.print("R ");
System.out.print("S ");
}
public static void main(String[] args) {
Stone st = new Stone();
new Thread(st).start();
new Thread(st).start();
}
}
One of the answers is:
The output could be
P Q P Q
I marked this answer as correct. My reasoning:
- We are starting two threads.
- First one enters
run()
. - According to JLS 15.26.1, it firstly evaluates
1 - id
. Result is0
. It is stored on the thread's stack. We are just about to save that0
to staticid
, but... - Boom, scheduler chooses the second thread to run.
- So, the second thread enters
run()
. Staticid
is still1
, so he executes methodpick()
.P Q
is printed. - Scheduler chooses first thread to run. It takes
0
from its stack and saves to staticid
. So, the first thread also executespick()
and printsP Q
.
However, in the book it's written that this answer is incorrect:
It is incorrect because the line
id = 1 - id
swaps the value ofid
between0
and1
. There is no chance for the same method to be executed twice.
I don't agree. I think there is some chance for the scenario I presented above. Such swap is not atomic. Am I wrong?