Поиск по этому блогу

среда, 24 июля 2013 г.

Java ожидаем завершение группы потоков.

  Всем привет. Давненько не писал. А собственно решил сегодня статейку набросать для того - чтобы привести в ней код для многопоточности в java и уделить внимание ожиданию события которое называается: группа потоков завершила работу.
  Сначала код, а потом разберёмся.

Main.java
/**
 * User: dimka3210
 * Date: 24.07.13
 * Time: 22:52
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        ThreadGroup group = new ThreadGroup("group");

        for (int i = 0; i < 10; i++) {
            new Thread(group, new ChildThread()).start();
            System.err.println("Active: " + group.activeCount());
        }

        while(group.activeCount() > 0) {
            System.err.println("Active: >" + group.activeCount());
            Thread.sleep(200);
        }
    }
}
ChildThread.java
/**
 * User: dimka3210
 * Date: 24.07.13
 * Time: 22:54
 */
public class ChildThread implements Runnable {
    long sleepTime;

    public ChildThread() {
        sleepTime = (long) (Math.random() * 1000);
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " run!");
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println(Thread.currentThread().getName() + " end!");
        }
    }
}
Этот вариант кода показывает что потоки независимы друг от друга и могут курить каждый по разному.

Вывод в консоли
Thread-0 run!
Active: 1
Active: 2
Active: 3
Active: 4
Active: 5
Active: 6
Active: 7
Active: 8
Active: 9
Thread-1 run!
Thread-3 run!
Thread-4 run!
Thread-5 run!
Thread-6 run!
Active: 10
Active: >10
Thread-7 run!
Thread-2 run!
Thread-9 run!
Thread-8 run!
Thread-7 end!
Active: >9
Thread-2 end!
Active: >8
Thread-5 end!
Thread-4 end!
Active: >6
Thread-3 end!
Thread-6 end!
Thread-9 end!
Thread-1 end!
Thread-0 end!
Active: >1
Thread-8 end!

А давайте попробуем изменить случайное время ожидание на одинаковое, и посмотрим в каком порядке потоки отработают.

Ищем это
sleepTime = (long) (Math.random() * 1000);
Меняем например на 500
sleepTime = (long) 500; 

И что мы видим?
Thread-0 run!
Active: 1
Thread-1 run!
Active: 2
Active: 3
Active: 4
Active: 5
Active: 6
Active: 7
Active: 8
Active: 9
Active: 10
Active: >10
Thread-4 run!
Thread-5 run!
Thread-3 run!
Thread-2 run!
Thread-7 run!
Thread-6 run!
Thread-9 run!
Thread-8 run!
Active: >10
Active: >10
Thread-0 end!
Thread-1 end!
Thread-4 end!
Thread-3 end!
Thread-2 end!
Thread-7 end!
Thread-6 end!
Thread-5 end!
Thread-9 end!
Thread-8 end!
А видим мы что потоки завершиются неупорядоченно. А значит на это полагаться нельзя ни в коем случае. Так же в одном из потоков может произойти ошибка, и всё пойдёт не так, как мы планировали.

Но нас интересует закончила группа потоков работу или нет. Именно для этого в этом примере я использовал ThreadGroup. Если с английским всё в порядке, можно сходить на сайт oracle и почитать у них. Но мы ведь здесь, а не там, поэтому расскажу в кратце для чего она (группа) нужна.

Нужна она нам по 2-м причинам:
  1. Убить группу поток целиком.
  2. Узнать кол-во работающих потоков в данной группе.
С группой работать просто. В первом варианте ей нужно вызвать метод interrupt() что завершит всю группу потоков, во втором вызвать метод avtiveCount() и он вернёт нам кол-во работающих потоков.

А этот код
while(group.activeCount() > 0) {
            System.err.println("Active: >" + group.activeCount());
            Thread.sleep(200);
        }
Просто расскажет нам о выполнении всех потоков.
Думаю понятно написал, если что не так, жду комментариев.

Комментариев нет:

Отправить комментарий

Количество·просмотров