Java руководство для начинающих - Шилдт Герберт (2012)
-
Год:2012
-
Название:Java руководство для начинающих
-
Автор:
-
Жанр:
-
Оригинал:Английский
-
Язык:Русский
-
Издательство:Вильямс
-
Страниц:316
-
ISBN:978-5-8459-1770-6
-
Рейтинг:
-
Ваша оценка:
Java руководство для начинающих - Шилдт Герберт читать онлайн бесплатно полную версию книги
В том цикле while, в котором вызывается метод wait (), проверяется значение переменной state. Значение "tocked", означающее завершение цикла, будет установлено только после выполнения метода tock (). Этот цикл предотвращает продолжение исполнения потока в результате ложной активизации. Если по окончании ожидания в переменной state не будет присутствовать значение "tocked", значит, имела место ложная активизация, и метод wait () будет вызван снова.
Метод tock () является почти точной копией метода tick (). Его отличие состоит лишь в том, что он выводит на экран слово "Tock" и присваивает переменной state значение "tocked". Следовательно, когда метод tock() вызывается, он выводит на экран слово "Tock", вызывает метод notify (), а затем переходит в состояние ожидания. Если проанализировать работу сразу двух потоков, то станет ясно, что за вызовом метода tick () тотчас следует вызов метода tock (), после чего снова вызывается метод tick (), и т.д. В итоге оба метода синхронизируют друг друга.
При остановке имитатора работы часов вызывается метод not if у (). Это нужно для того, чтобы возобновить исполнение ждущего потока. Как упоминалось выше, в обоих методах, tick() и tock (), после вывода сообщения на экран вызывается метод wait (). В результате при остановке имитатора работы часов один из потоков обязательно будет находиться в состоянии ожидания. Следовательно, последний вызов метода notify () необходим. В качестве эксперимента попробуйте удалить вызов метода notify () и посмотрите, что при этом произойдет. Вы увидите, что программа зависнет, и вам придется завершить ее нажатием комбинации клавиш . Дело в том, что когда метод tock () в последний раз получает управление, он вызывает метод wait (), после чего не происходит вызов метода not if у (), позволяющего завершиться методу tock (). В итоге метод tock () остается в состоянии бесконечного ожидания.
Если у вас еще остаются сомнения по поводу того, что методы wait () и notify () необходимы для организации нормального выполнения программы, имитирующей работу часов, замените в ее исходном коде класс TickTock приведенным ниже его вариантом. Он отличается тем, что в нем удалены вызовы методов wait () и notify ().
// В этой версии вызовы методов wait() и notify() отсутствуют,
class TickTock {
String state; // содержит сведения о состоянии часов
synchronized void tick(boolean running) {
if(!running) { // остановить часы
state = "ticked";
return;
}
System.out.print("Tick ");
state = "ticked"; // установить текущее состояние после такта "тик"
}
synchronized void tock(boolean running) {
if(!running) { // остановить часы
state = "tocked";
return;
}
System.out.println("Tock") ;
state = "tocked"; // установить текущее состояние после такта "так"
}
}
Теперь программа выводит на экран следующие сообщения:
Tick Tick Tick Tick Tick Tock
Tock
Tock
Tock
Tock
Это происходит потому, что методы tick() и tock() не взаимодействуют друг с другом.
Приостановка, возобновление и остановка потоков
Иногда оказывается полезно приостановить или даже полностью прекратить исполнение потока. Допустим, отдельный поток используется для отображения времени. Если пользователю не нужны часы на экране, то отображающий их поток можно приостановить. Независимо от причин, по которым требуется временная остановка потока, сделать это нетрудно, как, впрочем, и возобновить исполнение потока.
Механизмы приостановки, возобновление и остановки потоков менялись в разных версиях Java. До появления версии Java 2 для этих целей применялись методы suspend (), resume () и stop (), определенные в классе Thread. Ниже приведены общие формы их объявления.
final void resume()
final void suspend()
final void stop()