executorservice介面繼承了executor介面,定義了一些生命週期的方法
public inte***ce executorservice extends executor
本文,我們逐一分析裡面的每個方法。
首先,我們需要建立乙個任務**,這段任務**主要是隨機生成含有10個字元的字串
/**
* 隨機生成10個字元的字串
* @author dream-victor
* */
public class task1 implements callable
return sb.tostring();
}}
然後,我們還需要乙個長任務,這裡我們預設是沉睡10秒,
/**
* 長時間任務
* * @author dream-victor
* */
public class longtask implements callable
}
ok,所有前期準備完畢,下面我們就來分析一下executorservice介面中和生命週期有關的這些方法:
1、shutdown方法:這個方法會平滑地關閉executorservice,當我們呼叫這個方法時,executorservice停止接受任何新的任務且等待已經提交的任務執行完成(已經提交的任務會分兩類:一類是已經在執行的,另一類是還沒有開始執行的),當所有已經提交的任務執行完畢後將會關閉executorservice。這裡我們先不舉例在下面舉例。
2、awaittermination方法:這個方法有兩個引數,乙個是timeout即超時時間,另乙個是unit即時間單位。這個方法會使執行緒等待timeout時長,當超過timeout時間後,會監測executorservice是否已經關閉,若關閉則返回true,否則返回false。一般情況下會和shutdown方法組合使用。例如:
executorservice service = executors.newfixedthreadpool(4);
service.submit(new task1());
service.submit(new task1());
service.submit(new longtask());
service.submit(new task1());
service.shutdown();
while (!service.awaittermination(1, timeunit.seconds))
system.out.println("執行緒池已經關閉");
這段**中,我們在第三次提交了乙個長任務,這個任務將執行10秒沉睡,緊跟著執行了一次shutdown()方法,假設:這時executorservice被立即關閉,下面呼叫service.awaittermination(1, timeunit.seconds)方法時應該返回true,程式執行結果應該只會列印出:「執行緒池已經關閉」。但是,真實的執行結果如下:
執行緒池沒有關閉
執行緒池沒有關閉
執行緒池沒有關閉
執行緒池沒有關閉
執行緒池沒有關閉
執行緒池沒有關閉
執行緒池沒有關閉
執行緒池沒有關閉
執行緒池沒有關閉
執行緒池已經關閉
這說明我們假設錯誤,service.awaittermination(1, timeunit.seconds)每隔一秒監測一次executorservice的關閉情況,而長任務正好需要執行10秒,因此會在前9秒監測時executorservice為未關閉狀態,而在第10秒時已經關閉,因此第10秒時輸出:執行緒池已經關閉。這也驗證了shutdown方法關閉executorservice的條件。
3、shutdownnow方法:這個方法會強制關閉executorservice,它將取消所有執行中的任務和在工作佇列中等待的任務,這個方法返回乙個list列表,列表中返回的是等待在工作佇列中的任務。例如:
executorservice service = executors.newfixedthreadpool(3);
service.submit(new longtask());
service.submit(new longtask());
service.submit(new longtask());
service.submit(new longtask());
service.submit(new longtask());
listrunnables = service.shutdownnow();
system.out.println(runnables.size());
while (!service.awaittermination(1, timeunit.milliseconds))
system.out.println("執行緒池已經關閉");
這段**中,我們限制了執行緒池的長度是3,提交了5個任務,這樣將有兩個任務在工作佇列中等待,當我們執行shutdownnow方法時,executorservice被立刻關閉,所以在service.awaittermination(1, timeunit.milliseconds)方法校驗時返回的是false,因此沒有輸出:執行緒池沒有關閉。而在呼叫shutdownnow方法時,我們接受到了乙個list,這裡包含的是在工作佇列中等待執行的任務,由於執行緒池長度為3,且執行的都是長任務,所以當提交了三個任務後執行緒池已經滿了,剩下的兩次提交只能在工作佇列中等待,因此我們看到runnables的大小為2,結果如下:
2
執行緒池已經關閉
4、isterminated方法:這個方法會校驗executorservice當前的狀態是否為「terminated」即關閉狀態,當為「terminated」時返回true否則返回false。例如:
executorservice service = executors.newfixedthreadpool(3);
service.submit(new task1());
service.submit(new task1());
service.submit(new longtask());
service.shutdown();
system.out.println(system.currenttimemillis());
while (!service.isterminated())
system.out.println(system.currenttimemillis());
這段**我們執行了兩個正常的任務和乙個長任務,然後呼叫了shutdown方法,我們知道呼叫shutdown方法並不會立即關閉executorservice,這時我們記錄一下監測迴圈執行前的時間,在沒有關閉前我們一直進入乙個空迴圈中,直到 executorservice關閉後退出迴圈,這裡我們知道長任務執行時間大約為10秒,我們看一下上述程式執行結果:
1303298818621
1303298828634
相差:10013毫秒,轉換一下除以1000,得到相差大約10秒
這10秒正好是長任務執行的時間,因此在 executorservice正常關閉後isterminated方法返回true。
5、isshutdown方法:這個方法在executorservice關閉後返回true,否則返回false。方法比較簡單不再舉例。
以上討論是基於threadpoolexecutor的實現,不同的實現會有所不同需注意。
執行緒池ExecutorService
執行緒池 任務提交到執行緒池,而不是直接交給某執行緒,執行緒池拿到任務後,它在內部找空閒的執行緒進行執行 封裝 任務是提交給執行緒池,乙個執行緒只能執行乙個任務,但可以同時向乙個執行緒池提交多個任務。建立固定大小的執行緒池 建立快取執行緒池 如何實現執行緒死掉後重新啟動?答案 建立單一執行緒池exe...
執行緒十四 ExecutorService
executorservice不僅能呼叫runnable的任務,它還提供了呼叫callable任務的方法。callable任務中的call方法能夠返回任務執行的結果,同時還可以丟擲受檢的異常,call方法宣告了乙個throws exception子句。為了描述executorservice的應用,我...
ExecutorService執行緒池
executorservice 建立多執行緒的步驟 1。定義執行緒類 class handler implements runnable 2。建立executorservice執行緒池 3。呼叫執行緒池操作 幾種不同的executorservice執行緒池物件 1.newcachedthreadpo...