一、概述
到目前為止,我們已經能夠聲明並使一個線程任務運行起來了。但是遇到一個問題:現在定義的任務都沒有任何返回值,那么加入我們希望一個任務運行結束后告訴我一個結果,該結果表名任務執行成功或失敗,此時該怎么辦呢?
答案是使用Callable。之前定義的任務都直接實現了Runnable,該接口的run方法並無返回值。而Callable的call方法可以根據你傳入的泛型參數返回對應類型的數據。
二、實現
1.實現Callable接口,定義可返回結果的線程任務
public class TaskCallable implements Callable<String>{ private int id; public TaskCallable(int id){ this.id = id; } @Override public String call() throws Exception { return "result of taskWithResult "+id; } }
注意,泛型參數String表示的是該任務執行之后返回結果的類型。
2.將該任務交給線程執行者executor,讓他來代理執行這些線程
ExecutorService exec = Executors.newCachedThreadPool();//工頭 ArrayList<Future<String>> results = new ArrayList<Future<String>>();// for(int i = 0 ; i < 10 ;i++){ results.add(exec.submit(new TaskCallable(i)));//submit返回一個Future,代表了即將要返回的結果 }
注意,此時需要使用executor的submit方法來調用Callable的call。
該方法將返回一個Future接口的對象,它的泛型參數代表了call方法要返回的參數類型。
3.Future類型
簡單的了解了下Future類型:按照名字判斷該類型對象代表了線程執行完成后的結果,所以叫Future。那么在獲取該類型存放的線程運行結果時,可能該線程並未運行完畢,所以稱其為“將來的結果”。
- 首先,可以用isDone()方法來查詢Future是否已經完成,任務完成后,可以調用get()方法來獲取結果
- 如果不加判斷直接調用get方法,此時如果線程未完成,get將阻塞,直至結果准備就緒