執行緒執行者(九)執行者取消一個任務
宣告:本文是《 Java 7 Concurrency Cookbook 》的第四章,作者: Javier Fernández González 譯者:許巧輝 校對:方騰飛
執行者取消一個任務
當你使用執行者工作時,你不得不管理執行緒。你只實現Runnable或 Callable任務和把它們提交給執行者。執行者負責建立執行緒,線上程池中管理它們,當它們不需要時,結束它們。有時候,你想要取消已經提交給執行者 的任務。在這種情況下,你可以使用Future的cancel()方法,它允許你做取消操作。在這個指南中,你將學習如何使用這個方法來取消已經提交給執行者的任務。
準備工作…
這個指南的例子使用Eclipse IDE實現。如果你使用Eclipse或其他IDE,如NetBeans,開啟它並建立一個新的Java專案。
如何做…
按以下步驟來實現的這個例子:
1.建立Task類,指定實現Callable介面,並引數化為String型別。實現call()方法,寫入一條資訊到控制檯,並使這個執行緒在迴圈中睡眠100毫秒。
public class Task implements Callable<String> { @Override public String call() throws Exception { while (true){ System.out.printf("Task: Test\n"); Thread.sleep(100); } }
2.實現示例的主類,建立Main類,實現main()方法。
public class Main { public static void main(String[] args) {
3. 使用Executors類的newCachedThreadPool()方法建立ThreadPoolExecutor物件。
ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newCachedThreadPool();
4.建立Task物件。
Task task=new Task();
5.使用submit()方法提交任務給執行者。
System.out.printf("Main: Executing the Task\n"); Future<String> result=executor.submit(task);
6.使主任務睡眠2秒。
try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }
7.使用通過submit()方法返回的Future物件result的cancel()方法,取消任務的執行。傳入true值作為cancel()方法的引數。
System.out.printf("Main: Canceling the Task\n"); result.cancel(true);
8.將isCancelled()方法和isDone()的呼叫結果寫入控制檯,驗證任務已取消,因此,已完成。
System.out.printf("Main: Canceled: %s\n",result.isCanceled()); System.out.printf("Main: Done: %s\n",result.isDone());
9.使用shutdown()方法結束執行者,寫入資訊(到控制檯)表明程式結束。
executor.shutdown(); System.out.printf("Main: The executor has finished\n");
它是如何工作的…
當你想要取消你已提交給執行者的任務,使用Future介面的cancel()方法。根據cancel()方法引數和任務的狀態不同,這個方法的行為將不同:
- 如果這個任務已經完成或之前的已被取消或由於其他原因不能被取消,那麼這個方法將會返回false並且這個任務不會被取消。
- 如果這個任務正在等待執行者獲取執行它的執行緒,那麼這個任務將被取消而且不會開始它的執行。如果這個任務已經正在執行,則視方法的引數情況而定。 cancel()方法接收一個Boolean值引數。如果引數為true並且任務正在執行,那麼這個任務將被取消。如果引數為false並且任務正在執行,那麼這個任務將不會被取消。
以下截圖顯示該示例的執行輸出:
不止這些…
如果你使用Future物件的get()方法來控制一個已被取消的任務,這個get()方法將丟擲CancellationException異常。
參見
- 在第4章,執行緒執行者中的執行者執行返回結果的任務指南