Java多線程 Callable和Future
文章目錄
- Java多線程 Callable和Future
-
- 1、簡介
- 2、使用
1、簡介
(1)先來了解一下Callable 接口
Callable是類似于Runnable的接口,實作Callable接口的類和實作Runnable的類都是可被其他線程執行的任務。Callable接口的定義如下:
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
Callable的類型參數是傳回值的類型。例如:
Callable<Integer>表示一個最終傳回Integer對象的異步計算。
(2)Future儲存異步計算的結果。實際應用中可以啟動一個計算,将Future對象交給某個線程,然後執行其他操作。Future對象的所有者在結果計算好之後就可以獲得它。Future接口具有下面的方法:
public interface Future<V> {
//可以用cancel方法取消該計算。如果計算還沒有開始,它被取消且不再開始。
//如果計算處于運作之中,那麼如果mayInterrupt參數為true,它就被中斷
boolean cancel(boolean mayInterruptIfRunning);
//判斷是夠被取消
boolean isCancelled();
//如果計算還在進行,isDone方法傳回false;如果完成了,則傳回true。
boolean isDone();
//調用被阻塞,直到計算完成
V get() throws InterruptedException, ExecutionException;
//設定等待時間,get方法的調用逾時,抛出一個TimeoutException異常
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}
(3) FutureTask包裝器是一種非常便利的機制,同時實作了Future和Runnable接口。FutureTask有2個構造方法
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
建立線程的步驟一般如下:
(1)建立Callable接口的實作類,并實作call()方法,然後建立該實作類的執行個體;
(2)使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了Callable對象的call()方法的傳回值
(3)使用FutureTask對象作為Thread對象的target建立并啟動線程(因為FutureTask實作了Runnable接口)
(4)調用FutureTask對象的get()方法來獲得子線程執行結束後的傳回值。
2、使用
執行個體:
package callableTest;
import java.util.concurrent.*;
/**
* Callable與Future的應用
* Future取得的結果類型和Callable傳回的結果類型必須一緻,這是通過泛型來實作。
* Callable要采用ExecutorService的submit方法送出,傳回的future對象可以取消 * 任務。
* CompletionService用于送出一組Callable任務,其take方法傳回已完成的一個*Callable任務對應的Future對象。
*
**/
public class CallableTest {
public static void main(String args[]) throws InterruptedException, ExecutionException {
ExecutorService service = Executors.newSingleThreadExecutor();
Future<String> future = service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "hello world";
}
});
System.out.println("等待結果中");
System.out.println("得到的結果為:" + future.get());
ExecutorService service2 = Executors.newFixedThreadPool(10);
CompletionService<Integer> completionService = new ExecutorCompletionService<>(service2);
for(int i = 0; i < 10; ++i){
final int temp = i;
completionService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return temp;
}
});
}
for(int i = 0; i < 10; ++i){
System.out.println(completionService.take().get());
}
service.shutdown();
service2.shutdown();
}
}
結果:
等待結果中
得到的結果為:hello world
0
1
2
3
4
5
6
7
8
9