Thread线程是否执行完成,我们可以调用join方法然后等待线程执行完成;那在使用线程池的时候,我们如何知道线程已经执行完成了?本文就带给大家五种判断的方式:
- isTerminated() 方式,在执行 shutdown() ,关闭线程池后,判断是否所有任务已经完成。
- ThreadPoolExecutor 的 getCompletedTaskCount() 方法,判断完成任务数和全部任务数是否相等。
- CountDownLatch计数器,使用闭锁计数来判断是否全部完成。
- 手动维护一个公共计数 ,原理和闭锁类似,就是更加灵活。
- 使用submit向线程池提交任务,Future判断任务执行状态。
方法一:isTerminated()
测试代码
package pool;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author 百里
*/
public class BaiLiIsShutdownThreadPoolDemo {
/**
* 创建一个最大线程数15的线程池
*/
public static ThreadPoolExecutor pool = new ThreadPoolExecutor(
10,
15,
0L,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(10));
/**
* 线程执行方法,随机等待0到10秒
*/
private static void sleepMethod(int index){
try {
long sleepTime = new Double(Math.random() * 10000).longValue();
Thread.sleep(sleepTime);
System.out.println("当前线程执行结束: " + index);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 方法一:isTerminated
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
int index = i;
pool.execute(() -> sleepMethod(index));
}
pool.shutdown();
while (!pool.isTerminated()){
Thread.sleep(1000);
System.out.println("还没停止。。。");
}
System.out.println("全部执行完毕");
}
}
上述代码处理逻辑在主线程中进行循环判断,全部任务是否已经完成。
这里有两个主要方法:
- shutdown() :对线程池进行有序关闭。调用该方法后,线程池将不再接受新的任务,但会继续执行已提交的任务。如果线程池已经处于关闭状态,则对该方法的调用没有额外的作用。
- isTerminated() :判断线程池中的所有任务是否在关闭后完成。只有在调用了shutdown()或shutdownNow()方法后,所有任务执行完毕,才会返回true。需要注意的是,在调用shutdown()之前调用isTerminated()方法始终返回false。
优缺点分析
优点 :操作简单。
缺点 :需要关闭线程池。并且日常使用是将线程池注入到Spring容器,然后各个组件中统一用同一个线程池,不能直接关闭线程池。
方法二:getCompletedTaskCount()
测试代码
package pool;
import java.util.concurrent.*;