天天看點

線程執行者(六)運作多個任務并處理所有結果

聲明:本文是《 java 7 concurrency cookbook 》的第四章,作者: javier fernández gonzález 譯者:許巧輝 校對:方騰飛,葉磊

運作多個任務并處理所有結果

執行者架構允許你在不用擔心線程建立和執行的情況下,并發的執行任務。它還提供了future類,這個類可以用來控制任務的狀态,也可以用來獲得執行者執行任務的結果。

如果你想要等待一個任務完成,你可以使用以下兩種方法:

如果任務執行完成,future接口的isdone()方法将傳回true。

threadpoolexecutor類的awaittermination()方法使線程進入睡眠,直到每一個任務調用shutdown()方法之後完成執行。

這兩種方法都有一些缺點。第一個方法,你隻能控制一個任務的完成。第二個方法,你必須等待一個線程來關閉執行者,否則這個方法的調用立即傳回。

threadpoolexecutor類提供一個方法,允許你送出任務清單給執行者,并且在這個清單上等待所有任務的完成。在這個指南中,你将學習如何使用這個特性,實作一個示例,執行3個任務,并且當它們完成時将結果列印出來。

準備工作…

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

如何做…

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

1.建立result類,存儲這個示例中并發任務産生的結果。

<code>public class result {</code>

2.聲明兩個私有屬性。一個string屬性,名為name,另一個int屬性,名為value。

<code>private string name;</code>

<code>private int value;</code>

3.實作相應的get()和set()方法,用來設定和擷取name和value屬性的值。

4.建立task類,實作callable接口,參數化為result類型。

<code>public class task implements callable&lt;result&gt; {</code>

5.聲明一個私有string屬性,名為name。

6.實作task類構造器,初始化這個屬性。

7.實作這個類的call()方法,在本例中,它将傳回一個result對象。

8.首先,寫入一個資訊到控制台,表明任務開始。

<code>system.out.printf("%s: staring\n",this.name);</code>

9.然後,等待一個随機時間。

10.在result對象中傳回一個計算5個随機數的總和的int值。

11.建立result對象,用任務的名稱和前面操作結果來初始化它。

12.寫入一個資訊到控制台,表明任務已經完成。

<code>system.out.println(this.name+": ends");</code>

13.傳回result對象。

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

list tasklist=new arraylist&lt;&gt;();

for (int i=0; i&lt;3; i++){

task task=new task(i);

tasklist.add(task);

}

...try {

resultlist=executor.invokeall(tasklist);

} catch (interruptedexception e) {

e.printstacktrace();

}.使用shutdown()方法結束執行者。

executor.shutdown();

寫入處理future對象清單任務的結果。

system.out.println("main: printing the results");

for (int i=0; ifuture future=resultlist.get(i);

try {

result result=future.get();

system.out.println(result.getname()+": "+result.

getvalue());

} catch (interruptedexception | executionexception e) {

繼續閱讀