Создание нескольких потоков
По той же схеме, что создание одного дочернего потока, реализуется создание нескольких потоков. В листинге 4 приведен пример программы, в которой создаются три дочерних потока.
Листинг4.Создание нескольких дочерних потоков
// Импорт класса Date:
import java.util.Date;
// Класс NewThread наследует класс Thread:
class NewThread extends Thread{
// Параметры потока (название, время задержки, количество итераций):
private String name;
private int time;
private int count;
// Конструктор:
NewThread(String name,int time,int count){
super(name);
this.name=name;
System.out.print("Создан новый поток: "+name+". ");
// Отображение даты и времени:
System.out.println("Время: "+new Date()+".");
this.time=time;
this.count=count;
// Запуск потока:
start();}
// Переопределение метода run():
public void run(){
try{
for(int i=1;i<=count;i++){
System.out.print("Поток: "+name+". Сообщение "+i+" из "+count+". ");
// Отображение даты и времени:
System.out.println("Время: "+new Date()+".");
// Приостановка потока:
Thread.sleep(time);}
}catch(InterruptedException e){
System.out.println("Прерывание потока"+name);}
finally{
System.out.print("Поток \""+name+"\" работу завершил! ");
// Отображение даты и времени:
System.out.println("Время: "+new Date()+".");}
}}
class MultiThreadDemo{
// Исключение InterruptedException в методе main() не обрабатывается:
public static void main(String args[]) throws InterruptedException{
System.out.print("Начало работы! ");
// Отображение даты и времени:
System.out.println("Время: "+new Date()+".");
// Создание трех дочерних потоков:
new NewThread("Красный",5000,5);
new NewThread("Желтый",6000,4);
new NewThread("Зеленый",7000,3);
// Приостановка главного потока:
Thread.sleep(30000);
System.out.print("Работа программы завершена! ");
// Отображение даты и времени:
System.out.println("Время: "+new Date()+".");
}}
Несмотря на значительно больший объем программного кода по сравнению с предыдущим примером, в данной программе принципиальных изменений практически нет. В основном речь идет о «косметических» мерах. В первую очередь следует отметить, что конструктор класса NewThread, наследующего класс Thread, видоизменен так, что принимает три аргумента: имя создаваемого потока и два целочисленных параметра. Первый параметр определяет величину задержки при выводе потоком сообщений, второй — количество таких сообщений. Эти значения (аргументы конструктора) записываются в закрытые поля класса name, time и count соответственно.
Основу метода run(), который переопределяется в классе NewThread и задает функциональность потока (то есть выполняемый в потоке код), составляет цикл. Количество итераций задается полем count (которое, в свою очередь, передается третьим аргументом конструктору). За каждую итерацию выводится сообщение с названием потока (параметр name), номером сообщения, ожидаемым количеством сообщений этого потока, а также текущими датой и временем. Для получения даты и времени используется анонимный объект класса Date. Класс Date импортируется командой import java.util.Date в заголовке программы, а безымянный объект создается командой new Date(). При передаче этого объекта аргументом функции println() выводятся системные дата и время.
После вывода сообщения на экран командой Thread.sleep(time) производится приостановка выполнения потока на время time (в миллисекундах) — параметр передается вторым аргументом конструктору класса NewThread.
В конце выполнения потока выводится соответствующее сообщение с именем потока и временем завершения работы. Обращаем внимание, что в этом сообщении имя потока заключается в двойные кавычки, а сам символ двойных кавычек вводится в текст с помощью предваряющей косой черты.
В главном методе программы в классе MultiThreadDemo выводится сообщение о начале работы с указанием времени начала. Затем следующими командами создаются три анонимных объекта класса NewThread, каждый из которых запускает дочерний поток:
new NewThread("Красный",5000,5);
new NewThread("Желтый",6000,4);
new NewThread("Зеленый",7000,3);
После этого командой Thread.sleep(30000) на 30 секунд приостанавливается выполнение главного потока, чтобы успели закончить работу дочерние потоки. Затем главным потоком выводится сообщение о завершении работы программы (с указанием времени завершения). Результат выполнения программы может иметь следующий вид:
Начало работы! Время: Sat Sep 19 23:39:36 EEST 2009.
Создан новый поток: Красный. Время: Sat Sep 19 23:39:36 EEST 2009.
Создан новый поток: Желтый. Время: Sat Sep 19 23:39:36 EEST 2009.
Создан новый поток: Зеленый. Время: Sat Sep 19 23:39:36 EEST 2009.
Поток: Красный. Сообщение 1 из 5. Время: Sat Sep 19 23:39:36 EEST 2009.
Поток: Желтый. Сообщение 1 из 4. Время: Sat Sep 19 23:39:36 EEST 2009.
Поток: Зеленый. Сообщение 1 из 3. Время: Sat Sep 19 23:39:36 EEST 2009.
Поток: Красный. Сообщение 2 из 5. Время: Sat Sep 19 23:39:41 EEST 2009.
Поток: Желтый. Сообщение 2 из 4. Время: Sat Sep 19 23:39:42 EEST 2009.
Поток: Зеленый. Сообщение 2 из 3. Время: Sat Sep 19 23:39:43 EEST 2009.
Поток: Красный. Сообщение 3 из 5. Время: Sat Sep 19 23:39:46 EEST 2009.
Поток: Желтый. Сообщение 3 из 4. Время: Sat Sep 19 23:39:48 EEST 2009.
Поток: Зеленый. Сообщение 3 из 3. Время: Sat Sep 19 23:39:50 EEST 2009.
Поток: Красный. Сообщение 4 из 5. Время: Sat Sep 19 23:39:51 EEST 2009.
Поток: Желтый. Сообщение 4 из 4. Время: Sat Sep 19 23:39:54 EEST 2009.
Поток: Красный. Сообщение 5 из 5. Время: Sat Sep 19 23:39:56 EEST 2009.
Поток "Зеленый" работу завершил! Время: Sat Sep 19 23:39:57 EEST 2009.
Поток "Желтый" работу завершил! Время: Sat Sep 19 23:40:00 EEST 2009.
Поток "Красный" работу завершил! Время: Sat Sep 19 23:40:01 EEST 2009.
Работа программы завершена! Время: Sat Sep 19 23:40:06 EEST 2009.
Наличие момента времени, в который выводится сообщение, позволяет провести достаточно скрупулезный анализ особенностей «наложения» потоков друг на друга. Желающие могут заняться этим самостоятельно. Еще одна особенность представленного кода состоит в том, что в методе main() не производится обработка исключения InterruptedException. Поэтому в сигнатуру метода вынесено сообщение о том, что метод может выбросить такое исключение (throws InterruptedException).
Дата добавления: 2016-06-22; просмотров: 1300;