天天看點

線程執行者(四)執行者執行傳回結果的任務

執行者執行傳回結果的任務

executor framework的一個優點是你可以并發執行傳回結果的任務。java并發api使用以下兩種接口來實作:

callable:此接口有一個call()方法。在這個方法中,你必須實作任務的(處理)邏輯。callable接口是一個參數化的接口。意味着你必須表明call()方法傳回的資料類型。

future:此接口有一些方法來保證callable對象結果的擷取和管理它的狀态。

在這個指南中,你将學習如何實作傳回結果的任務,并在執行者中運作它們。

準備工作…

這個指南的例子使用eclipse ide實作。如果你使用eclipse或其他ide,如netbeans,打開它并建立一個新的java項目。

如何做…

按以下步驟來實作的這個例子:

1.建立factorialcalculator類,指定它實作callable接口,并參數化為integer類型。

2.聲明一個私有的,類型為integer,名為number的屬性,用來存儲任務将要計算出的數。

3.實作factorialcalculator構造器,初始化這個屬性。

4.實作call()方法。這個方法将傳回factorialcalculator的number屬性的階乘。

5.首先,建立和初始化在這個方法中使用的局部變量。

6.如果數是1或0,則傳回1。否則,計算這個數的階乘。出于教學目的,在兩次乘之間,令這個任務睡眠20毫秒。

7.操作結果的資訊寫入控制台。

8.傳回操作結果。

9.實作這個示例的主類,建立main類,實作main()方法。

10.使用executors類的newfixedthreadpool()方法建立threadpoolexecutor來運作任務。傳入參數2。

11.建立future<integer>對象的數列。

12.建立random類産生的随機數。

13.生成0到10之間的10個随機數。

14.建立一個factorialcaculator對象,傳入随機數作為參數。

15.調用執行者的submit()方法來送出factorialcalculator任務給執行者。這個方法傳回future<integer>對象來管理任務,并且最終擷取它的結果。

16.添加future對象到之前建立的數列。

17.建立一個do循環來監控執行者的狀态。

18.首先,寫入資訊到控制台,表明使用執行者的getcompletedtasknumber()方法獲得的已完成的任務數。

19.然後,對于數列中的10個future對象,使用isdone()方法,将資訊寫入(到控制台)表明它們所管理的任務是否已經完成

20.令這個線程睡眠50毫秒

21.如果執行者中的已完成任務數小于10,重複這個循環。

22.将獲得的每個任務的結果寫入控制台。對于每個future對象,通過它的任務使用get()方法擷取傳回的integer對象。

23.然後,在控制台列印這個數。

24.最後,調用執行者的shutdown()方法來結束這個執行者。

它是如何工作的…

在這個指南中,你已經學習了如何使用callable接口來啟動傳回結果的并發任務。你已經使用factorialcalculator類實作了callable接口,并參數化為integer類型作為結果類型。是以,integer就作為call()方法的傳回類型。

main類是這個示例的另一個關鍵點。它使用submit()方法送出一個callable對象給執行者執行。這個方法接收callable對象參數,并且傳回一個future對象,你可以以這兩個目标來使用它:

你可以控制任務的狀态:你可以取消任務,檢查任務是否已經完成。基于這個目的,你已經使用isdone()方法來檢查任務是否已經完成。

你 可以擷取call()方法傳回的結果。基于這個目的,你已經使用了get()方法。這個方法會等待,直到callable對象完成call()方法的執 行,并且傳回它的結果。如果線程在get()方法上等待結果時被中斷,它将抛出interruptedexception異常。如果call()方法抛出 異常,這個方法會抛出executionexception異常。

不止這些…

當你調用future對象的get()方法,并且這個對象控制的任務未完成,這個方法會阻塞直到任務完成。future接口提供其他版本的get()方法:

get(long timeout, timeunit unit):這個版本的get方法,如果任務的結果不可用,等待它在指定的時間内。如果時間逾時,并且結果不可用,這個方法傳回null值。 timeunit類是個枚舉類,有如下常量:days,hours,microseconds, milliseconds, minutes,,nanoseconds 和seconds。

參見

在第4章,線程執行者中的建立線程執行者指南

在第4章,線程執行者中的運作多個任務并處理第一個結果指南

在第4章,線程執行者中的運作多個任務并處理所有結果指南

繼續閱讀