Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Текст лекции Многопоточность сокращенный вариан...doc
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
221 Кб
Скачать
☆

Использование методов isAlive() и join()

Итак, главный поток должен быть последним завершающимся потоком. В предшествующих примерах это выполнялось вызовом метода sleep() в main() с достаточно длинной задержкой, чтобы гарантировать, что все до­черние потоки закончатся до завершения главного потока.

Существуют два других способа определения, закончился ли поток. Один из них позволяет вызывать метод isAlive() на потоке. Этот метод определен в Thread и его общая форма выглядит так:

final boolean isAlive()

Метод isAlive() возвращает true, если поток, на котором он вызывается — все еще выполняется. В противном случае возвращается false.

Другой способ ожидания завер­шения потока - вызов метода join() следующего формата:

final void join() throws InterruptedException

Этот метод ждет завершения потока, на котором он вызван. Дополнительные формы join() позволяют определять максимальное время ожидания завершения указанного потока.

Ниже показана улучшенная версия предшествующего примера, использую­щая join() и гарантирующая, что главный поток останавливается послед­ним. Она также демонстрирует метод isAlive() (DemoJoin.java).

// Использование join() для ожидания окончания потока.

class NewThread implements Runnable

{

String name; // имя потока

Thread t;

NewThread(String threadname) {

name = threadname;

t = new Thread(this, name);

System.out.println("Новый поток: " + t);

t.start(); // старт потока

}

// Это точка входа потока.

public void run()

{ try

{

for(int i = 5; i > 0; i--) {

System.out.println(name + ": " + i);

Thread.sleep(1000);

}

} catch (InterruptedException e) {

System.out.println(name + " прерван.");

}

System.out.println(name + " завершен.");

}

}

class DemoJoin {

public static void main(String args[]) {

NewThread ob1 = new NewThread("Первый");

NewThread ob2 = new NewThread("Второй");

NewThread ob3 = new NewThread("Третий");

System.out.println("Первый поток выполняется: " + ob1.t.isAlive());

System.out.println("Второй поток выполняется: " + ob2.t.isAlive());

System.out.println("Третий поток выполняется: " + ob3.t.isAlive());

// ждать завершения потоков

try {

System.out.println("Ждите завершения потоков.");

ob1.t.join();

ob2.t.join();

ob3.t.join();

} catch (InterruptedException e) {

System.out.println("Прерывание главного потока");

}

System.out.println("Первый поток выполняется: " + ob1.t.isAlive());

System.out.println("Второй поток выполняется: " + ob2.t.isAlive());

System.out.println("Третий поток выполняется: " + ob3.t.isAlive());

System.out.println("Завершение главного потока.");

}

}

Пример вывода этой программы:

Новый поток: Thread[Первый,5,main]

Новый поток: Thread[Второй,5,main]

Новый поток: Thread[Третий,5,main]

Первый: 5

Первый поток выполняется: true

Второй поток выполняется: true

Третий поток выполняется: true

Ждите завершения потоков.

Третий: 5

Второй: 5

Первый: 4

Третий: 4

Второй: 4

Третий: 3

Первый: 3

Второй: 3

Третий: 2

Второй: 2

Первый: 2

Третий: 1

Первый: 1

Второй: 1

Первый завершен.

Третий завершен.

Второй завершен.

Первый поток выполняется: false

Второй поток выполняется: false

Третий поток выполняется: false

Завершение главного потока.

После возврата из join() потоки прекращают выпол­няться.