Java多執行緒——Callable、Future和FutureTask
通過Thread或Runnable建立的執行緒,都需要重寫run方法,而run方法的返回是void的,所以使用這種方式無法獲取執行緒執行結果。但java提供了其他類和方法來獲取執行緒執行結果,主要的類有Callable、Future和FutureTask。
Callable
Callable是個泛型介面 Callable ,該介面中只有個call()方法,並且返回值也為 V,常和ExecutorService中的 submit 方法配合使用。
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
Future
Future可以對具體的 Runnable 或者 Callable 任務的執行結果進行取消、查詢是否完成、獲取結果等操作。可以通過get方法獲取執行結果,該方法會阻塞直到任務返回結果。
Future 介面中有5個方法:
cancel()方法用來取消任務,如果取消任務成功則返回true,如果取消任務失敗則返回false;
isCancelled方法表示任務是否被取消成功,如果在任務正常完成前被取消成功,則返回 true;
isDone方法表示任務是否已經完成,若任務完成,則返回true;
get()方法用來獲取執行結果,這個方法會產生阻塞,會一直等到任務執行完畢才返回;
get(long timeout, TimeUnit unit)用來獲取執行結果,如果在指定時間內,還沒獲取到結果,就直接返回null。
FutureTask
FutureTask類實現了 RunnableFuture 介面,RunnableFuture 繼承了 Runnable 介面和 Future 介面,所以FutureTask既可以作為Runnable被執行緒執行,又可以作為Future得到Callable的返回值。
FutureTask提供了2個構造器:
public FutureTask(Callable<V> callable) {
}
所以實現了Callable的物件可以通過該構造器得到一個FutureTask,而FutureTask可以直接給執行緒來執行,然後通過FutureTask取回執行結果。
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
可以看出該構造器通過 Executors.callable()
把Runnable轉換為Callable,其內部使用了介面卡 RunnableAdapter。因此FutureTask實現了Future、Runnable,又是包裝了Callable( 如果是Runnable最終也會被轉換為Callable ), 它是這兩者的合體。
示例程式碼
ExecutorService的兩個方法:
<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
可以看出,通過第一個方法直接執行Callable,然後從Future中獲取結果;或者用 FutureTask(Callable callable) 構造個FutureTask(它實現了Runable介面)物件用第二個方法獲取返回結果,或者直接就在一個執行緒中執行。
程式碼實現:
public class ThreadCallablePractice {
public void callableTest() throws Exception{
ExecutorService executorService = Executors.newFixedThreadPool(3);
Future<String> future = executorService.submit(new Task());
executorService.shutdown();
System.out.println(future.get());
}
public void futureTaskTest() throws Exception{
FutureTask<String> futureTask = new FutureTask<String>(new Task());
//new Thread(futureTask).start();
//或者仍用執行緒池
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(futureTask);
executorService.shutdown();
System.out.println(futureTask.get());
}
public static void main(String[] args) throws Exception{
ThreadCallablePractice practice = new ThreadCallablePractice();
//practice.callableTest();
practice.futureTaskTest();
}
}
class Task implements Callable<String>{
public String call(){
System.out.println(Thread.currentThread().getName() + " is working");
return "callable result";
}
}
執行結果
pool-1-thread-1 is working
callable result
參考資料
Java併發程式設計:Callable、Future和FutureTask
Callable和Future、FutureTask的使用
相關文章
- Java多執行緒之Callable,Future,FutureTaskJava執行緒
- Java多執行緒21:多執行緒下的其他元件之CyclicBarrier、Callable、Future和FutureTaskJava執行緒元件
- Java多執行緒-Callable和FutureJava執行緒
- 大話Android多執行緒(四) Callable、Future和FutureTaskAndroid執行緒
- 執行緒執行 之 Runnable Callable Future ,FutureTask ExcutorService概覽執行緒
- Java併發程式設計:Callable、Future和FutureTaskJava程式設計
- Java多執行緒之FutureTaskJava執行緒
- 搞懂Runnable Callable Future FutureTask 及應用
- Runnable、Callable、Executor、Future、FutureTask關係解讀
- java多執行緒系列之future機制Java執行緒
- java 多執行緒設計模式之futureJava執行緒設計模式
- Java多執行緒帶返回值的Callable介面Java執行緒
- Future --- 多執行緒設計模式執行緒設計模式
- 在Java中使用Callable和FutureJava
- Java多執行緒類FutureTask原始碼閱讀以及淺析Java執行緒原始碼
- Java多執行緒——執行緒Java執行緒
- 多執行緒系列(十九) -Future使用詳解執行緒
- Java之實現多執行緒的方式三:實現Callable介面(結合執行緒池使用)Java執行緒
- 多執行緒和多執行緒同步執行緒
- Java多執行緒-執行緒中止Java執行緒
- Java多執行緒——執行緒池Java執行緒
- 多執行緒07:async、future、packaged_task、promise執行緒PackagePromise
- 【Java多執行緒】輕鬆搞定Java多執行緒(二)Java執行緒
- Java 併發和多執行緒(一) Java併發性和多執行緒介紹[轉]Java執行緒
- JAVA多執行緒詳解(3)執行緒同步和鎖Java執行緒
- java——多執行緒Java執行緒
- java 多執行緒Java執行緒
- 【Java】多執行緒Java執行緒
- JAVA 多執行緒 ??Java執行緒
- java多執行緒Java執行緒
- Java - 多執行緒Java執行緒
- java 多執行緒守護執行緒Java執行緒
- Java多執行緒-執行緒通訊Java執行緒
- Java多執行緒-執行緒狀態Java執行緒
- Java多執行緒(2)執行緒鎖Java執行緒
- java多執行緒9:執行緒池Java執行緒
- Java多執行緒之執行緒中止Java執行緒
- 【java多執行緒】(二)執行緒停止Java執行緒