Со страницы 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. Нет возможности для того, чтобы один и тот же метод выполнялся дважды.
Я не согласен. Я думаю, что есть шанс для сценария, который я представил выше. Такой обмен не является атомарным. Я не прав?