接上一章,本文主要對shutdown()、shutdownNow()、awaitTerminate(long timeout,TimeUnit unit)這三個方法采用問答的形式分別進行講解。本文實驗基於JDK版本1.8。
1、shutdown()
問:shutdown()有什么功能?
答:阻止新來的任務提交,對已經提交了的任務不會產生任何影響。當已經提交的任務執行完后,它會將那些閑置的線程(idleWorks)進行中斷,這個過程是異步的。
問:如何阻止新來的任務提交?
答:通過將線程池的狀態改成SHUTDOWN,當再將執行execute提交任務時,如果測試到狀態不為RUNNING,則拋出rejectedExecution,從而達到阻止新任務提交的目的。
問:為何對提交的任務不產生任何影響?
答:在調用中斷任務的方法時,它會檢測workers中的任務,如果worker對應的任務沒有中斷,並且是空閑線程,它才會去中斷。另外的話,workQueue中的值,還是按照一定的邏輯順序不斷的往works中進行輸送的,這樣一來,就可以保證提交的任務按照線程本身的邏輯執行,不受到影響。
2、shutdownNow()
問:shutdownNow()有什么功能?
答:阻止新來的任務提交,同時會中斷當前正在運行的線程,即workers中的線程。另外它還將workQueue中的任務給移除,並將這些任務添加到列表中進行返回。
問:如何阻止新來的任務提交?
答:通過將線程池的狀態改成STOP,當再將執行execute提交任務時,如果測試到狀態不為RUNNING,則拋出rejectedExecution,從而達到阻止新任務提交的目的.
問:如果我提交的任務代碼塊中,正在等待某個資源,而這個資源沒到,但此時執行shutdownNow(),會出現什么情況?
答:當執行shutdownNow()方法時,如遇已經激活的任務,並且處於阻塞狀態時,shutdownNow()會執行1次中斷阻塞的操作,此時對應的線程報InterruptedException,如果后續還要等待某個資源,則按正常邏輯等待某個資源的到達。例如,一個線程正在sleep狀態中,此時執行shutdownNow(),它向該線程發起interrupt()請求,而sleep()方法遇到有interrupt()請求時,會拋出InterruptedException(),並繼續往下執行。在這里要提醒注意的是,在激活的任務中,如果有多個sleep(),該方法只會中斷第一個sleep(),而后面的仍然按照正常的執行邏輯進行。
3、awaitTermination(long timeout,TimeUnit unit)
簡單來說,awaitTermination會一直等待,直到線程池狀態為TERMINATED或者,等待的時間到達了指定的時間。
4、補充
//runState != RUNNING
System.out.println("-----isShutdown-------:"+tpe.isShutdown());
//state == SHUTDOWN || state == STOP
System.out.println("-----isTerminating----:"+tpe.isTerminating());
//runState == TERMINATED
System.out.println("-----isTerminated-----:"+tpe.isTerminated());