最近看了下Java线程池的源码,ExecutorService里面关于shutdown和shutdownNow的注释不太能理解啥意思。
直接翻译字面意思是,开启一个有序的关闭,先前提交的任务会被执行,但不接受新任务。如果已关闭,则调用不会产生任何其他影响。但是这个方法不会等待已提交任务完成执行。
这里可以有几个含义:
- 肯定不接受新任务了
- 已提交的任务是否会执行完呢
- 会,但是不会等
- 这里不会等的意思是线程池支持用户关闭线程池,但是用户没需要等待里面已提交的任务完成了才可以继续做别的事,可以用非阻塞调用去理解。调用后线程池isShutDown变为true,但是isTerminated要等到已提交任务都完成才会变成true
下面写了一段程序去验证了下
/**
* Initiates an orderly shutdown in which previously submitted
* tasks are executed, but no new tasks will be accepted.
* Invocation has no additional effect if already shut down.
*
* <p>This method does not wait for previously submitted tasks to
* complete execution. Use {@link #awaitTermination awaitTermination}
* to do that.
void shutdown();
public class ExecutorShutDownTest {
public static final Integer TASK_NUM = 10;
private static ExecutorService pool = new ThreadPoolExecutor(
2, 4,
2, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10),
new ShutDownThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy()
);;
public static void main(String[] args) throws InterruptedException, IOException {
for (int i = 0; i < TASK_NUM; i++) {
pool.execute(new ThreadTask(i));
}
System.out.println("Error happened, terminate executing tasks");
pool.shutdown();
if (pool.isShutdown()) {
System.out.println("The ThreadPool is shutdown");
}
for (int i = TASK_NUM; i < TASK_NUM * 2; i++) {
pool.execute(new ThreadTask(i));
}
System.out.println("Main ends");
while (!pool.isTerminated()) {
}
System.out.println("exit");
}
}
class ThreadTask implements Runnable {
private Integer taskNum;
public ThreadTask(Integer taskNum) {
this.taskNum = taskNum;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " start to execute Task " + taskNum + " =====>");
try {
TimeUnit.SECONDS.sleep(5);
System.out.println("^_^ Task + " + taskNum + " done!");
} catch (InterruptedException e) {
System.out.println("┭┮﹏┭┮ Task" + taskNum + " interrupt unexpectedly");
}
}
}
class ShutDownThreadFactory implements ThreadFactory {
private AtomicInteger threadNum = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
threadNum.incrementAndGet();
return new Thread(r,"Thread" + threadNum.get());
}
}
下面是执行的结果,可以对比下上面的解释理解下
Thread1 start to execute Task 0 =====>
Thread2 start to execute Task 1 =====>
Error happened, terminate executing tasks
The ThreadPool is shutdown
Main ends
^_^ Task + 0 done!
^_^ Task + 1 done!
Thread1 start to execute Task 2 =====>
Thread2 start to execute Task 3 =====>
^_^ Task + 3 done!
^_^ Task + 2 done!
Thread2 start to execute Task 4 =====>
Thread1 start to execute Task 5 =====>
^_^ Task + 4 done!
^_^ Task + 5 done!
Thread2 start to execute Task 6 =====>
Thread1 start to execute Task 7 =====>
^_^ Task + 6 done!
^_^ Task + 7 done!
Thread2 start to execute Task 8 =====>
Thread1 start to execute Task 9 =====>
^_^ Task + 8 done!
^_^ Task + 9 done!
exit