В существующих ответах сказано, что join()
каждый поток.
Но есть несколько способов получить массив / список потоков:
- Добавить тему в список при создании.
- Используйте
ThreadGroup
для управления потоками.
Следующий код будет использовать этот ThreadGruop
подход. Сначала он создает группу, затем при создании каждого потока указывает группу в конструкторе, позже можно получить массив потоков черезThreadGroup.enumerate()
Код
SyncBlockLearn.java
import org.testng.Assert;
import org.testng.annotations.Test;
public class SyncBlockLearn {
private static final int TD_COUNT = 5;
private static final int ROUND_PER_THREAD = 100;
private static final long INC_DELAY = 10;
@Test
public void syncBlockTest() throws InterruptedException {
Counter ct = new Counter();
ThreadGroup tg = new ThreadGroup("runner");
for (int i = 0; i < TD_COUNT; i++) {
new Thread(tg, ct, "t-" + i).start();
}
Thread[] tArr = new Thread[TD_COUNT];
tg.enumerate(tArr);
for (Thread t : tArr) {
t.join();
}
System.out.printf("\nfinal count: %d\n", ct.getCount());
Assert.assertEquals(ct.getCount(), TD_COUNT * ROUND_PER_THREAD);
}
static class Counter implements Runnable {
private final Object lkOn = new Object();
private int count = 0;
@Override
public void run() {
System.out.printf("[%s] begin\n", Thread.currentThread().getName());
for (int i = 0; i < ROUND_PER_THREAD; i++) {
synchronized (lkOn) {
System.out.printf("[%s] [%d] inc to: %d\n", Thread.currentThread().getName(), i, ++count);
}
try {
Thread.sleep(INC_DELAY);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("[%s] end\n", Thread.currentThread().getName());
}
public int getCount() {
return count;
}
}
}
Основной поток будет ждать завершения всех потоков в группе.