OCPの291ページからJava SE 6プログラマー模擬試験、質問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();
}
}
_
答えの1つは次のとおりです。
出力は_
P Q P Q
_になる可能性があります
私はこの答えを正しいとマークしました。私の推論:
run()
に入ります。1 - id
_を評価します。結果は_0
_です。スレッドのスタックに保存されます。その_0
_を静的id
に保存しようとしていますが...run()
に入ります。静的id
は_1
_のままなので、メソッドpick()
を実行します。 _P Q
_が出力されます。0
_を取得し、静的id
に保存します。したがって、最初のスレッドもpick()
を実行し、_P Q
_を出力します。しかし、本にはこの答えが間違っていると書かれています:
_
id = 1 - id
_という行は、_0
_と_1
_の間でid
の値を交換するため、正しくありません。同じメソッドが2回実行される可能性はありません。
同意しません。上記のシナリオには、ある程度のチャンスがあると思います。このようなスワップはアトミックではありません。私が間違っている?
私が間違っている?
いいえ、あなたは完全に正しいです-あなたの例のタイムラインもそうです。
アトミックではないことに加えて、同期がなく、フィールドが揮発性でない場合、id
への書き込みが他のスレッドによって取得されるとは限りません。
このような参照資料が正しくないことはやや当惑しています:(