最近看了下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