executorservice是java中對線程池定義的一個接口,它<code>java.util.concurrent</code>包中,在這個接口中定義了和背景任務執行相關的方法:

除此之外,executorservice還繼承了<code>executor</code>接口(注意區分executor接口和executors工廠類),這個接口隻有一個<code>execute()</code>方法,最後我們看一下整個繼承樹:
建立一個什麼樣的executorservice的執行個體(即線程池)需要g根據具體應用場景而定,不過java給我們提供了一個<code>executors工廠類</code>,它可以幫助我們很友善的建立各種類型executorservice線程池,executors一共可以建立下面這四類線程池:
備注:executors隻是一個工廠類,它所有的方法傳回的都是<code>threadpoolexecutor</code>、<code>scheduledthreadpoolexecutor</code>這兩個類的執行個體。
executorservice有如下幾個執行方法:
這個方法接收一個runnable執行個體,并且異步的執行,請看下面的執行個體:
這個方法有個問題,就是沒有辦法獲知task的執行結果。如果我們想獲得task的執行結果,我們可以傳入一個callable的執行個體(下面會介紹)。
<code>submit(runnable)</code>和<code>execute(runnable)</code>差別是前者可以傳回一個future對象,通過傳回的future對象,我們可以檢查送出的任務是否執行完畢,請看下面執行的例子:
如果任務執行完成,<code>future.get()</code>方法會傳回一個null。注意,future.get()方法會産生阻塞。
<code>submit(callable)</code>和<code>submit(runnable)</code>類似,也會傳回一個future對象,但是除此之外,submit(callable)接收的是一個callable的實作,callable接口中的<code>call()</code>方法有一個傳回值,可以傳回任務的執行結果,而runnable接口中的<code>run()</code>方法是<code>void</code>的,沒有傳回值。請看下面執行個體:
如果任務執行完成,future.get()方法會傳回callable任務的執行結果。注意,future.get()方法會産生阻塞。
<code>invokeany(...)</code>方法接收的是一個callable的集合,執行這個方法不會傳回future,但是會傳回所有callable任務中其中一個任務的執行結果。這個方法也無法保證傳回的是哪個任務的執行結果,反正是其中的某一個。請看下面執行個體:
大家可以嘗試執行上面代碼,每次執行都會傳回一個結果,并且傳回的結果是變化的,可能會傳回“task2”也可是“task1”或者其它。
<code>invokeall(...)</code>與 <code>invokeany(...)</code>類似也是接收一個callable集合,但是前者執行之後會傳回一個future的list,其中對應着每個callable任務執行後的future對象。情況下面這個執行個體:
當我們使用完成executorservice之後應該關閉它,否則它裡面的線程會一直處于運作狀态。
舉個例子,如果的應用程式是通過main()方法啟動的,在這個main()退出之後,如果應用程式中的executorservice沒有關閉,這個應用将一直運作。之是以會出現這種情況,是因為executorservice中運作的線程會阻止jvm關閉。
如果要關閉executorservice中執行的線程,我們可以調用<code>executorservice.shutdown()</code>方法。在調用shutdown()方法之後,executorservice不會立即關閉,但是它不再接收新的任務,直到目前所有線程執行完成才會關閉,所有在shutdown()執行之前送出的任務都會被執行。
如果我們想立即關閉executorservice,我們可以調用<code>executorservice.shutdownnow()</code>方法。這個動作将跳過所有正在執行的任務和被送出還沒有執行的任務。但是它并不對正在執行的任務做任何保證,有可能它們都會停止,也有可能執行完成。