天天看點

線程執行者(十二)執行者控制被拒絕的任務

執行者控制被拒絕的任務

當你想要結束執行者的執行,你使用shutdown()方法來表明它的結束。執行者等待正在運作或等待它的執行的任務的結束,然後結束它們的執行。

如果你在shutdown()方法和執行者結束之間,送出任務給執行者,這個任務将被拒絕,因為執行者不再接收新的任務。threadpoolexecutor類提供一種機制,在調用shutdown()後,不接受新的任務。

在這個指南中,你将學習如何通過實作rejectedexecutionhandler,在執行者中管理拒絕任務。

準備工作…

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

如何做…

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

1.建立rejectedtaskcontroller類,實作rejectedexecutionhandler接口。實作這個接口的rejectedexecution()方法。寫入被拒絕任務的名稱和執行者的名稱與狀态到控制台。

<code>1</code>

<code>public</code> <code>class</code> <code>rejectedtaskcontroller </code><code>implements</code>

<code>2</code>

<code>rejectedexecutionhandler {</code>

<code>3</code>

<code>@override</code>

<code>4</code>

<code>public</code> <code>void</code> <code>rejectedexecution(runnable r, threadpoolexecutor executor) {</code>

<code>5</code>

<code>system.out.printf(</code><code>"rejectedtaskcontroller: the task %s has been rejected\n"</code><code>,r.tostring());</code>

<code>6</code>

<code>system.out.printf(</code><code>"rejectedtaskcontroller: %s\n"</code><code>,executor.tostring());</code>

<code>7</code>

<code>system.out.printf(</code><code>"rejectedtaskcontroller: terminating:%s\n"</code><code>,executor.isterminating());</code>

<code>8</code>

<code>system.out.printf(</code><code>"rejectedtakscontroller: terminated:%s\n"</code><code>,executor.isterminated());</code>

<code>9</code>

<code>}</code>

2.實作task類,實作runnable接口。

<code>public</code> <code>class</code> <code>task </code><code>implements</code> <code>runnable{</code>

3.聲明私有的、string類型的屬性name, 用來存儲任務的名稱。

<code>private</code> <code>string name;</code>

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

<code>public</code> <code>task(string name){</code>

<code>this</code><code>.name=name;</code>

5.實作run()方法,寫入資訊到控制台,表明這個方法開始執行。

<code>public</code> <code>void</code> <code>run() {</code>

<code>system.out.println(</code><code>"task "</code><code>+name+</code><code>": starting"</code><code>);</code>

6.等待一段随機時間。

<code>try</code> <code>{</code>

<code>long</code> <code>duration=(</code><code>long</code><code>)(math.random()*</code><code>10</code><code>);</code>

<code>system.out.printf(</code><code>"task %s: reportgenerator: generating a report during %d seconds\n"</code><code>,name,duration);</code>

<code>timeunit.seconds.sleep(duration);</code>

<code>} </code><code>catch</code> <code>(interruptedexception e) {</code>

<code>e.printstacktrace();</code>

7.寫入資訊到控制台,表明方法的結束。

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

8.重寫tostring()方法,傳回任務的名稱。

<code>public</code> <code>string tostring() {</code>

<code>return</code> <code>name;</code>

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

<code>public</code> <code>class</code> <code>main {</code>

<code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) {</code>

10.建立一個rejectedtaskcontroller對象,管理拒絕的任務。

<code>rejectectaskcontroller controller=</code><code>new</code> <code>rejectectaskcontroller();</code>

11.使用executors類的newcachedthreadpool()方法,建立threadpoolexecutor。

<code>threadpoolexecutor executor=(threadpoolexecutor) executors.newcachedthreadpool();</code>

12.建立執行者的拒絕任務控制器。

<code>executor.setrejectedexecutionhandler(controller);</code>

13.建立任務并送出它們給執行者。

<code>system.out.printf(</code><code>"main: starting.\n"</code><code>);</code>

<code>for</code> <code>(</code><code>int</code> <code>i=</code><code>0</code><code>; i&lt;</code><code>3</code><code>; i++) {</code>

<code>task task=</code><code>new</code> <code>task(</code><code>"task"</code><code>+i);</code>

<code>executor.submit(task);</code>

14.使用shutdown()方法,關閉執行者。

<code>system.out.printf(</code><code>"main: shutting down the executor.\n"</code><code>);</code>

<code>executor.shutdown();</code>

15.建立其他任務并送出給執行者。

<code>system.out.printf(</code><code>"main: sending another task.\n"</code><code>);</code>

<code>task task=</code><code>new</code> <code>task(</code><code>"rejectedtask"</code><code>);</code>

16.寫入資訊到控制台,表明程式結束。

<code>system.out.println(</code><code>"main: end"</code><code>);</code>

<code>system.out.printf(</code><code>"main: end.\n"</code><code>);</code>

這是如何工作的…

以下截圖顯示示例的執行結果:

線程執行者(十二)執行者控制被拒絕的任務

你可以看出當執行者關閉時,任務被拒絕送出。rejectectaskcontroller将有關于任務和執行者的資訊寫入到控制台。

為了管理執行者控制拒絕任務,你應該實作rejectedexecutionhandler接口。該接口有帶有兩個參數的方法rejectedexecution():

runnable對象,存儲被拒絕的任務

executor對象,存儲拒絕任務的執行者

每個被執行者拒絕的任務都會調用這個方法。你必須使用executor類的setrejectedexecutionhandler()方法設定拒絕任務的處理器。

不止這些…

當執行者接收任務時,會檢查shutdown()是否已經被調用了。如果被調用了,它拒絕這個任務。首先,它查找 setrejectedexecutionhandler()設定的處理器。如果有一個(處理器),它調用那個類的 rejectedexecution()方法,否則,它将抛rejectedexecutionexeption異常。這是一個運作時異常,是以你不需要 用catch語句來控制它。

參見

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

繼續閱讀