}
//--------------------------------------------------------------------------
public void init()
{ resize(320, 240);
// Сделать: Добавьте сюда код инициализации
}
//-------------------------------------------------------------------------
public void destroy()
{ // Сделать: Добавьте сюда код завершения работы апплета
}
//--------------------------------------------------------------------------
public void paint(Graphics g)
{ // Сделать: Добавьте сюда код перерисовки окна апплета
g. drawString("Running: " + Math. random(), 10, 20);
}
//--------------------------------------------------------------------------
public void start()
{ // если поток еще не создан, апплет создает
// новый поток как объект класса Thread
if (m_Multi == null)
{ m_Multi = new Thread(this); // создание потока
m_Multi. start(); // запуск потока
}
// Сделать: Добавьте сюда код, который должен
// работать при запуске апплета
}
//--------------------------------------------------------------------------
public void stop()
{ // когда пользователь покидает страницу,
// метод stop() класса Thread останавливает поток
if (m_Multi!= null) // если поток был создан
{ m_Multi.going = 0; //остановка потока
m_Multi = null; // сброс ссылки на поток
}
// Сделать: Добавьте сюда код, который должен
// работать при остановке апплета
}
// Метод, который работает в рамках отдельного потока.
// Он вызывает периодическое обновление окна апплета
//--------------------------------------------------------------------------
public void run()
{ // выполняем обновление окна в бесконечном цикле
while (true)
{ try
{ // вызов функции обновления
repaint();
// Сделать: Добавьте сюда код, который должен
// здесь работать в рамках отдельного потока
//выполнение небольшой задержки
Thread. sleep(50);
}
catch (InterruptedException e)
{ // Сделать: Добавьте сюда код, который должен
// здесь работать при генерации исключения
// если при выполнении задержки произошло
// исключение, останавливаем работу апплета
stop();
}
}
}
// Сделать: Добавьте сюда код, необходимый для работы
// создаваемого специализированного апплета
}
import java. awt.*;
import java. awt. event.*;
//============================================
// Этот класс действует как окно, в котором отображается апплет,
// когда он запускается как обычное приложение
//============================================
class MultiFrame extends Frame
{
// Конструктор класса
//--------------------------------------------------------------------------
public MultiFrame(String str)
{ super (str);
addWindowListener(new MyWindowAdapter());
// Сделать: Добавьте сюда код конструктора
}
class MyWindowAdapter extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
dispose();
System. exit(0);
}
}
}
Потоки (нити)
Класс Thread содержит несколько конструкторов и большое количество методов для управления потоков.
Некоторые методы класса Thread:
- currentThread - Возвращает ссылку на выполняемый в настоящий момент объект класса Thread sleep - Переводит выполняемый в данное время поток в режим ожидания в течение указанного промежутка времени start - Начинает выполнение потока. Это метод приводит к вызову соответствующего метода run() run - Фактическое тело потока. Этот метод вызывает после запуска потока stop - Останавливает поток // Устаревший метод isAlive - Определяет, является ли поток активным (запущенным и не остановленным) suspend - Приостанавливает выполнение потока // Устаревший метод resume - Возобновляет выполнение потока. Этот метод работает только после вызова метода suspend() setPriority - Устанавливает приоритет потока (принимает значение от MIN_PRIORITY до MAX_PRIORITY) getPriority - Возвращает приоритет потока wait() - Переводит поток в состояние ожидания выполнения условия, определяемого переменной условия join() - Ожидает, пока данный поток не завершит своего существования бесконечно долго или в течении некоторого времени setDaemon - Отмечает данный поток как поток-демон или пользовательский поток. Когда в системе останутся только потоки-демоны, программа на языке Java завершит свою работу isDaemon - Возвращает признак потока-демона
Для того, чтобы эффективно использовать потоки, необходимо уяснить их различные аспекты, а также особенности работы исполняющей системы языка Java. Рассмотрим атрибуты потоков.
Состояние потока
Во время своего существования поток может переходить во многие состояния, находясь в одном из нижеперечисленных состояний:
- Новый поток Выполняемый поток Невыполняемый поток Завершенный поток
Новый поток
При создании экземпляра потока этот поток приобретает состояние “Новый поток”:
Thread myThread=new Thread();
В этот момент для данного потока распределяются системные ресурсы; это всего лишь пустой объект. В результате все, что с ним можно делать - это запустить:
myThread.start();
Любой другой метод потока в таком состоянии вызвать нельзя, это приведет к возникновению исключительной ситуации.
Выполняемый поток
Когда поток получает метод start(), он переходит в состояние “Выполняемый поток”. Процессор разделяет время между всеми выполняемыми потоками согласно их приоритета
Невыполняемый поток
Если поток не находится в состоянии “Выполняемый поток”, то он может оказаться в состоянии “Невыполняемый поток”. Это состояние наступает тогда, когда выполняется одно из четырех условий:
- Поток был приостановлен. Это условие является результатом вызова метода suspend(). После вызова этого метода поток не находится в состоянии готовности к выполнению; его сначала нужно “разбудить” с помощью метода resume(). Это полезно в том случае, когда необходимо приостановить выполнение потока, не удаляя его. Поскольку метод suspend не рекомендуется к использованию, приостановка потока должна выполняться через управляющую переменную. Поток ожидает. Это условие является результатом вызова метода sleep(). После вызова этого метода поток переходит в состояние ожидания в течении некоторого определенного промежутка времени и не может выполняться до истечения этого промежутка Даже если ожидающий поток имеет доступ к процессору, он его не получит. Когда указанный промежуток времени пройдет, поток переходит в состояние “Выполняемый поток”. Метод resume() не может повлиять на процесс ожидания потока, этот метод применяется только для приостановленных потоков. Поток ожидает извещения. Это условие является результатом вызова метода wait(). С помощью этого метода потоку можно указать перейти в состояние ожидания выполнения условия, определяемого переменной условия, вынуждая его тем самым приостановить свое выполнение до тех пор, пока данное условие удовлетворяется. Какой бы объект не управлял ожидаемым условием, изменение состояния ожидающих потоков должно осуществляться посредством одного из двух методов этого потока - notify() или notifyAll(). Если поток ожидает наступление какого-либо события, он может продолжить свое выполнение только в случае вызова для него этих методов. Поток заблокирован другим потоком. Это условие является результатом блокировки операцией ввода-вывода или другим потоком. В этом случае у потока нет другого выбора, как ожидать до тех пор, пока не завершится команда ввода-вывода или действия другого потока. В этом случае поток считается невыполняемым, даже если он полностью готов к выполнению.
Завершенный поток
Когда метод run() завершается, поток переходит в состояние “Завершенный поток”.
Исключительные ситуации для потоков
Исполняющая система языка Java будет возбуждать исключительную ситуацию IllegalThreadStateException всякий раз, когда будет вызываться метод, которым поток не может оперировать в своем текущем состоянии.
Например, ожидающий поток не может работать с методом resume(). В этом случае поток занят ожиданием, он просто не знает, как реагировать на этот метод.
То же самое справедливо и в том случае, когда происходит попытка вызвать метод suspend() для потока, который не находится в состоянии “Выполняемый поток”. Если он уже был приостановлен, просто ожидает, ожидает условия или заблокирован операцией ввода-вывода, поток не понимает как работать с этим методом.
Всякий раз при вызове метода потока, который потенциально может привести к возникновению исключительной ситуации, необходимо обеспечить и способ обработки исключительных ситуаций для того, чтобы перехватывать любые возбуждаемые ситуации, например:
try
{ // здесь вызываются методы для потоков
......................................................................
}
catch(InterruptedException e)
{ // потоку был послан метод, которым он
// не может оперировать в данном состоянии,
// можно остановить поток его методом stop()
}
Приоритеты потоков
В языке Java каждый поток обладает приоритетом, который оказывает влияние на порядок его выполнения. Потоки с высоким приоритетом выполняются до потоков с низким приоритетом. Это существенно, поскольку возникают моменты, когда их необходимо разделить подобным образом
Поток наследует свой приоритет от потока, его создавшего. Если потоку не присвоен новый приоритет, он будет сохранять данный приоритет до своего завершения. Приоритет потока можно установить с помощью метода setPriority(), присваивая ему значение от MIN_PRIORITY до MAX_PRIORITY (константы класса Thread). По умолчанию потоку присваивается приоритет Thread. NORM_PRIORITY.
Порядок выполнения потоков и количество времени, которое они получат от процессора, - главные вопросы для разработчиков. Каждый поток должен разделять процессорное время с другими, не монополизируя систему.
Система, которая имеет дело со множеством выполняющихся потоков, может быть или приоритетная, или неприоритетная. Приоритетные системы гарантируют, что в любое время будет выполняться поток с самым высоким приоритетом. Виртуальная машина Java является приоритетной, то есть выполняться всегда будет поток с самым высоким приоритетом.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 |


