| |
{
}
synchronized(STask)
{
STask.notify();
}
}
}
Эта задача реализована в рамках отдельного класса, конструктору которого
передается ссылка на задачу, вызывающую метод wait. Эта ссылка хранится в поле
STask.
Обратите внимание, что хотя сам метод run не синхронизированный, вызов
метода notify выполняется в синхронизированном режиме. В качестве объекта
синхронизации выступает задача, для которой вызывается метод notify.
Ожидание завершения задачи
С помощью метода join вы можете выполнять ожидание завершения работы задачи,
для которой этот метод вызван.
Существует три определения метода join:
public final void join();
public final void join(long millis);
public final void join(long millis, int nanos);
Первый из них выполняет ожидание без ограничения во времени, для второго
ожидание будет прервано принудительно через millis миллисекунд, а для третьего
- через millis миллисекунд и nanos наносекунд. Учтите, что реально вы не
сможете указывать время с точностью до наносекунд, так как дискретность
системного таймера компьютера намного больше.
Приложение Synchro
Для иллюстрации способа синхронизации задач с помощью методов wait и notify
мы подготовили приложение Synchro. Внешне окно аплета этого приложения выглядит
точно так же, как и окно аплета Rectangles (рис. 1.2).
Напомним, что приложение Rectangles постоянно рисует закрашенные
прямоугольники случайного размера, расположения и цвета, для чего в методе run
организован бесконечный цикл с задержкой.
Приложение Synchro решает ту же самую задачу немного другим способом. Оно
создает две задачи. Первая задача рисует в цикле прямоугольники, однако вместо
задержки она ожидает извещение от другой задачи, вызывая для этого функцию wait.
Вторая задача, опять же в цикле, создает извещения, вызывая с задержкой метод
notify. Таким образом, вторая задача как бы управляет работой первой задачи.
Исходные тексты приложения
Исходные тексты приложения Synchro приведены в листинге 1.11.
Листинг 1.11. Файл Synchro\Synchro.javal
// =========================================================
// Демонстрация синхронизации двух задач
//
// (C) Фролов А.В, 1997
//
// E-mail: [email protected]
// WWW: http://www.glasnet.ru/~frolov
// или
// http://www.dials.ccas.ru/frolov
// =========================================================
import java.applet.*;
import java.awt.*;
// =========================================================
// Основной класс аплета
// =========================================================
public class Synchro extends Applet
{
// Ссылка на задачу рисования прямоугольников
DrawRectangles m_DrawRectThread = null;
// Ссылка на задачу, периодически разблокирующую задачу
// рисования прямоугольников
NotifyTask m_NotifyTaskThread = null;
// -------------------------------------------------------
// getAppletInfo
// Метод, возвращающей строку информации об аплете
// -------------------------------------------------------
public String getAppletInfo()
{
return "Name: Synchro\r\n" +
"Author: Alexandr Frolov\r\n" +
"E-mail: [email protected]" +
"WWW: http://www.glasnet.ru/~frolov" +
"Created with Microsoft Visual J++ Version 1.0";
}
// -------------------------------------------------------
// paint
// Метод paint, выполняющий рисование в окне аплета
// -------------------------------------------------------
public void paint(Graphics g)
{
// Определяем текущие размеры окна аплета
Dimension dimAppWndDimension = size();
// Выбираем в контекст отображения желтый цвет
g.setColor(Color.yellow);
// Закрашиваем внутреннюю область окна аплета
g.fillRect(0, 0,
dimAppWndDimension.width - 1,
dimAppWndDimension.height - 1);
// Выбираем в контекст отображения черный цвет
g.setColor(Color.black);
// Рисуем рамку вокруг окна аплета
g.drawRect(0, 0,
dimAppWndDimension.width - 1,
|
|