方法一、
使用 shutdown 方法,该方法会让线程池不在继续接收新的线程,直到没有线程后通过循环判断是否所有线程都执行完毕
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService exec = Executors.newFixedThreadPool(4);
for (int i = 0;i<10000;i++) {
exec.execute(() -> System.out.println("aaaaaaaaaaaaaaaaaaaaaa"));
}
exec.shutdown();
while(true){
if(exec.isTerminated()){
System.out.println("所有的子线程都结束了!");
break;
}
Thread.sleep(1000);
}
}
方法二、
通过 shutdown 将线程池不在接收新的线程,然后使用 awaitTermination 通过返回值 true 判断线程全部执行完成
public static void main(String[] args) throws ExecutionException, InterruptedException {
for (int i = 0;i<10000;i++) {
exec.execute(() -> System.out.println("aaaaaaaaaaaaaaaaaaaaaa"));
}
exec.shutdown();
//请求关闭、发生超时或者当前线程中断,无论哪一个首先发生之后,都将导致阻塞,直到所有任务完成执行。
boolean flag = exec.awaitTermination(1, TimeUnit.MINUTES);
if(flag){
System.out.println("结束了aaaa");
}
}
方法三、
判断线程池中的线程是否全部执行完毕的另外一种解决方案则是使用闭锁 (CountDownLatch) 来实现,CountDownLatch 是一种灵活的闭锁实现,它可以使一个或多个线程等待一组事件发生。闭锁状态包括一个计数器,该计数器被初始化为一个正数,表示需要等待的事件数量。countDown 方法递减计数器,表示有一个事件已经发生了,而 await 方法等待计数器达到零,即表示需要等待的事情都已经发生。可以使用闭锁来这样设计程序达到目的:
public class CountDownLatchApproach {
public static void main(String[] args) throws IOException, InterruptedException {
final int nThreads = 10;
final CountDownLatch endGate = new CountDownLatch(nThreads);
final File stream = new File("c:\\temp\\stonefeng\\stream.txt");
final OutputStream os = new FileOutputStream(stream);
final OutputStreamWriter writer = new OutputStreamWriter(os);
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < nThreads; i++) {
final int num = i;
Runnable task = new Runnable() {
@Override
public void run() {
try {
writer.write(String.valueOf(num)+"\n");
} catch (IOException e) {
e.printStackTrace();
} finally {
endGate.countDown();
}
}
};
exec.submit(task);
}
endGate.await();
writer.write("---END---\n");
writer.close();
}
}
作者:耳威巴帝
链接:https://www.jianshu.com/p/58bfd7f04bb5
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。