Всем привет. Давненько не писал. А собственно решил сегодня статейку набросать для того - чтобы привести в ней код для многопоточности в 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);
}
Просто расскажет нам о выполнении всех потоков.
Думаю понятно написал, если что не так, жду комментариев.