Со страницы 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();
}
}
Один из ответов:
Выходной сигнал может быть
P Q P Q
Я правильно ответил на этот ответ. Мои рассуждения:
- Мы начинаем два потока.
- Сначала вводится
run()
. - В соответствии с JLS 15.26.1 он сначала оценивает
1 - id
. Результат0
. Он хранится в стеке потоков. Мы собираемся сохранить это0
в staticid
, но... - Бум, планировщик выбирает второй поток для запуска.
- Итак, второй поток входит в
run()
. Статическийid
по-прежнему1
, поэтому он выполняет методpick()
.P Q
. - Планировщик выбирает первый поток для запуска. Он берет
0
из своего стека и сохраняет до статическогоid
. Итак, первый поток также выполняетpick()
и печатаетP Q
.
Однако в книге написано, что этот ответ неверен:
Это неверно, потому что строка
id = 1 - id
меняет значениеid
между0
и1
. Нет возможности для того, чтобы один и тот же метод выполнялся дважды.
Я не согласен. Я думаю, что есть шанс для сценария, который я представил выше. Такой обмен не является атомарным. Я не прав?