Java Урок 47: ПОТОКИ, isAlive(), join()

Использование методов isAlive() и join(). Иногда необходимо, чтобы главный поток завершался последним.

Скачать исходники для статьи можно ниже

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

К счастью, класс Thread предлагает средство,которое дает ответ на этот вопрос.

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

final Boolean isAlive()

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

Во-вторых, существует метод, который вы будете использовать чаще, чтобы дождаться завершения потока, а именно — метод join():

final void join() throws InetrruptedException

Этот метод ожидает завершение потока, для которого он вызван. Его имя отражает концепцию, что вызывающий поток ожидает, когда указанный поток присоединится к нему.

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

// Применение 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 obi = new NewThread("Одни");
      NewThread ob2 = new NewThread("Два");
      NewThread ob3 = new NewThread("Три");
      System.out.println("Поток Один запущен: "+ obi.t.isAlive());
      System.out.println("Поток Два запущен: "+ ob2.t.isAlive());
      System.out.println("Поток Три запущен: "+ оbЗ.t.isAlive());
      // ожидать завершения потоков
      try {
         System.out.println("Ожидание завершения потоков.");
         obi.t.join();
         ob2.t.join();
         ob3.t.join();
      } catch (InterruptedException e) {
         System.out.println("Главный поток прерван");
      }
      System.out.println("Поток Один запущен: "+ obi.t.isAlive());
      System.out.println("Поток Два запущен: "+ ob2.t.isAlive());
      System.out.println("Поток Три запущен: "+ оЬЗ.t.isAlive());
      System.out.println("Главный поток завершен.");
   }
}

Пример вывода этой программы показан ниже (ваш вывод может отличаться,
в зависимости от конкретной среды исполнения)
.
Новый поток: Thread[Одни,5,main] Новый поток: Thread[Два,5.main] Новый поток: Thread[Три,5,main] Поток Один запущен: true
Поток Два запущен: true
Поток Три запущен: true
Ожидание завершения потоков.
Один: 5
Два: 5
Три: 5
Один: 4
Два: 4
Три: 4
Один: 3
Два: 3
Три: 3
Один: 2
Два: 2
Три: 2
Один: 1
Два: 1
Три: 1
Два завершен.
Три завершен.
Один завершен.
Поток Один запущен: false
Поток Два запущен: false
Поток Три запущен: false
Главный поток завершен.

Как видите,после того, как вызовы метода join() вернут управление,
потоки прекращают работу.

Введите свой email адрес для того, чтобы подписаться на мой блог:


knopkisoc

Добавить комментарий