Ab Seite 291 der OCP Java SE 6 Programmer Practice Exams, Frage 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();
}
}
Eine der Antworten lautet:
Die Ausgabe könnte sein
P Q P Q
Ich habe diese Antwort als richtig markiert. Meine Argumentation:
- Wir starten zwei Threads.
- Zuerst tritt man ein
run()
. - Nach JLS 15.26.1 wird zunächst ausgewertet
1 - id
. Ergebnis ist0
. Es wird auf dem Stapel des Threads gespeichert. Wir sind gerade dabei, das0
statisch zu speichernid
, aber ... - Boom, Scheduler wählt den zweiten Thread aus, der ausgeführt werden soll.
- Also tritt der zweite Thread ein
run()
. Statischid
ist immer noch1
, also führt er die Methode auspick()
.P Q
wird gedruckt. - Der Scheduler wählt den ersten Thread aus, der ausgeführt werden soll. Es nimmt
0
von seinem Stapel und speichert in statischeid
. Der erste Thread wird also auch ausgeführtpick()
und gedrucktP Q
.
In dem Buch steht jedoch geschrieben, dass diese Antwort falsch ist:
Dies ist falsch, da die Zeile
id = 1 - id
den Wertid
zwischen0
und vertauscht1
. Es besteht keine Chance, dass dieselbe Methode zweimal ausgeführt wird.
Ich stimme nicht zu. Ich denke, es gibt eine Chance für das Szenario, das ich oben vorgestellt habe. Ein solcher Tausch ist nicht atomar. Liege ich falsch?