在OCP Java SE 6程序员实践考试的第291页中,问题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();
}
}
答案之一是:
输出可能是
P Q P Q
我将此答案标记为正确。我的推理:
- 我们正在启动两个线程。
- 第一个进入
run()
。 - 根据JLS 15.26.1,它首先进行评估
1 - id
。结果是0
。它存储在线程的堆栈中。我们即将将其保存0
为staticid
,但是... - 繁荣,调度程序选择第二个线程来运行。
- 因此,第二个线程进入
run()
。静态id
仍然是1
,所以他执行方法pick()
。P Q
打印。 - 调度程序选择要运行的第一个线程。它
0
从堆栈中取出并保存为staticid
。因此,第一个线程也将执行pick()
并打印P Q
。
但是,在书中写道,这个答案是不正确的:
这不正确,因为线路
id = 1 - id
交换价值id
之间0
和1
。相同的方法不可能两次执行。
我不同意 我认为上面介绍的方案有一定的机会。这种交换不是原子的。我错了吗?