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

А этот код
while(group.activeCount() > 0) {
            System.err.println("Active: >" + group.activeCount());
            Thread.sleep(200);
        }

Просто расскажет нам о выполнении всех потоков.
Думаю понятно написал, если что не так, жду комментариев.
Теги:
поток
Добавлено: 28 Сентября 2013 11:01:29 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...