public class ThreadTest {
public static void main(String[] args) {
System.out.println("main begin");
CountDownLatch cunt = new CountDownLatch(5);
List<String> out = new ArrayList<>();
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i=0;i<5;i++){
executorService.execute(new TaskTest(i+"",cunt,out));
}
try {
cunt.await();
}catch (Exception e){
}
executorService.shutdown();
System.out.println(out);
System.out.println("main out");
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class TaskTest implements Runnable{
private String name;
private CountDownLatch countDownLatch;
private List<String> result;
@Override
public void run() {
countDownLatch.countDown();
result.add(Thread.currentThread().getName()+":"+name);
System.out.println("thread:"+name);
}
}
主线程中打印的out理论上应该是:[11, 11, 11, 11, 11],但是会出现[null, 11, 11, 11, 11]或者[null, null, 11, 11, 11],是什么原因?
不用线程池的话,主线程中可以通过监测子线程的状态来判断。
public static void main(String[] args) {
System.out.println("main start");
ThreadGroup tg = new ThreadGroup("Parent ThreadGroup");
for (int j = 0; j < 10; j++) {
new Thread(tg, "t" + j) {
public void run() {
System.out.println("Thread: " + getName() + " running");
int small = 0;
int large = 10;
try {
Thread.sleep(1000 * (int) (Math.random() * (large - small + 1) + small));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
while (tg.activeCount() > 0) {
try {
System.out.println("Waiting for " + tg.activeCount() + " CThreads to Complete");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("main end");
}
public void run() {
countDownLatch.countDown();
result.add(Thread.currentThread().getName()+":"+name);
System.out.println("thread:"+name);
}
countDown()方法放在最后调用
改成下面这样,执行完逻辑之后才放开,确保业务逻辑先执行
@Override
public void run() {
result.add(Thread.currentThread().getName()+":"+name);
System.out.println("thread:"+name);
countDownLatch.countDown();
}
但是你这里还是有个问题,你的out数组不是线程安全的,我简单改了一下,
public static void main(String[] args) {
System.out.println("main begin");
CountDownLatch cunt = new CountDownLatch(5);
ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<>(5);
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i=0;i<5;i++){
int finalI = i;
executorService.execute(()->{
try {
queue.put(Thread.currentThread().getName()+":"+ finalI);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread:"+ finalI);
cunt.countDown();
});
}
try {
cunt.await();
}catch (Exception e){
e.printStackTrace();
}
executorService.shutdown();
while (queue.size()!=0){
System.out.println(queue.poll());
}
System.out.println("main out");
}