天天看點

線程執行者(九)執行者取消一個任務

執行者取消一個任務

當你使用執行者工作時,你不得不管理線程。你隻實作runnable或 callable任務和把它們送出給執行者。執行者負責建立線程,線上程池中管理它們,當它們不需要時,結束它們。有時候,你想要取消已經送出給執行者 的任務。在這種情況下,你可以使用future的cancel()方法,它允許你做取消操作。在這個指南中,你将學習如何使用這個方法來取消已經送出給執行者的任務。

準備工作…

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

如何做…

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

1.建立task類,指定實作callable接口,并參數化為string類型。實作call()方法,寫入一條資訊到控制台,并使這個線程在循環中睡眠100毫秒。

<code>1</code>

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

<code>2</code>

<code>@override</code>

<code>3</code>

<code>public</code> <code>string call() </code><code>throws</code> <code>exception {</code>

<code>4</code>

<code>while</code> <code>(</code><code>true</code><code>){</code>

<code>5</code>

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

<code>6</code>

<code>thread.sleep(</code><code>100</code><code>);</code>

<code>7</code>

<code>}</code>

<code>8</code>

2.實作示例的主類,建立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>

3. 使用executors類的newcachedthreadpool()方法建立threadpoolexecutor對象。

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

4.建立task對象。

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

5.使用submit()方法送出任務給執行者。

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

<code>future&lt;string&gt; result=executor.submit(task);</code>

6.使主任務睡眠2秒。

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

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

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

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

7.使用通過submit()方法傳回的future對象result的cancel()方法,取消任務的執行。傳入true值作為cancel()方法的參數。

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

<code>result.cancel(</code><code>true</code><code>);</code>

8.将iscancelled()方法和isdone()的調用結果寫入控制台,驗證任務已取消,是以,已完成。

<code>system.out.printf(</code><code>"main: canceled: %s\n"</code><code>,result.iscanceled());</code>

<code>system.out.printf(</code><code>"main: done: %s\n"</code><code>,result.isdone());</code>

9.使用shutdown()方法結束執行者,寫入資訊(到控制台)表明程式結束。

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

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

它是如何工作的…

當你想要取消你已送出給執行者的任務,使用future接口的cancel()方法。根據cancel()方法參數和任務的狀态不同,這個方法的行為将不同:

如果這個任務已經完成或之前的已被取消或由于其他原因不能被取消,那麼這個方法将會傳回false并且這個任務不會被取消。

如果這個任務正在等待執行者擷取執行它的線程,那麼這個任務将被取消而且不會開始它的執行。如果這個任務已經正在運作,則視方法的參數情況而定。 cancel()方法接收一個boolean值參數。如果參數為true并且任務正在運作,那麼這個任務将被取消。如果參數為false并且任務正在運作,那麼這個任務将不會被取消。

以下截圖顯示該示例的執行輸出:

線程執行者(九)執行者取消一個任務

不止這些…

如果你使用future對象的get()方法來控制一個已被取消的任務,這個get()方法将抛出cancellationexception異常。

參見

在第4章,線程執行者中的執行者執行傳回結果的任務指南

繼續閱讀