Callable、Future和FutureTask簡介
阿新 • • 發佈:2018-05-15
線程池 異步 rgs lex dem 抽象類 及其 down ide 1.
1. Runnable
和Callable<v>
、Future
及其實現類FutureTask
對比
Runnable
和Callable<v>
都是任務的抽象類,不同的是前者不會返回值,後者有返回值。兩者源碼如下:
Runnable
@FunctionalInterface public interface Runnable { public abstract void run(); }
Callable<V>
@FunctionalInterface public interface Callable<V> { V call() throws Exception; }
Future
及其實現類FutureTask
用來獲取異步計算結果的,說白了就是對具體的Runnable或者Callable對象任務執行的結果進行獲取get() get(x,y)
,取消cancel()
,判斷是否完成isDone()
和是否取消isCancelled()
等操作。其源碼如下:
public interface Future<V> {
//嘗試取消任務的執行,如果任務已經完成或者取消,則會嘗試將會失敗。
//如果參數是true,表示正在執行的任務可以中斷,
//此方法執行後,isDone總會返回true;如果返回true則isCancelled返回true;
boolean cancel(boolean mayInterruptIfRunning);
//如果任務在完成之前取消,返回true
boolean isCancelled();
//任務完成則返回TRUE,完成指正常結束、異常或者取消;
boolean isDone();
//阻塞獲取計算的完成,並且獲取結果
V get() throws InterruptedException, ExecutionException;
//在指定的時間內阻塞獲取計算結果
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
可以作為線程池ThreadPoolExecutor
的方法public <T> Future<T> submit(Callable<T> task)
的返回值,其get()
方法可以阻塞獲取Callable的call()
計算結果。
FutureTask
FutureTask
是RunnableFuture<v>
的實現類,而RunnableFuture<V>
是Runnable
和Future
的子接口(接口可以多繼承)。**註意FutureTask
實現了Runnable
接口。
2. 使用示範
展示使用Callable<V>
+Future<V>
和Callable<V>
+FutureTask<V>
提交有返回值的任務,並且異步獲取返回值。
Callable<V>
+Future<V>
:提交Callable
並獲取Future
類型的返回結果;Callable<V>
+FutureTask<V>
:將Callable
作為構造器參數,將自己並提交執行,然後使用其get
獲取結果。
CallableTask
public class CallableTask implements Callable<Integer> {
@Override
public Integer call() throws InterruptedException {
System.out.println("開始執行任務");
TimeUnit.SECONDS.sleep(1);
int sum=0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
System.out.println("結束任務執行");
return new Integer(sum);
}
}
FutureDemo
public class FutureDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor= Executors.newCachedThreadPool();
//fixme 提交Callable並獲取Future類型的返回結果
CallableTask task=new CallableTask();
Future<Integer> res=executor.submit(task);
executor.shutdown();
System.out.println("計算結果:"+res.get());
}
}
FutureTaskDemo
public class FutureTaskDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor= Executors.newCachedThreadPool();
//fixme 不是直接提交Callable,而是將Callable作為構造器參數,將自己並提交執行,然後使用其get獲取結果
CallableTask callableTask=new CallableTask();
FutureTask futureTask=new FutureTask(callableTask);
executor.submit(futureTask);
executor.shutdown();
System.out.println("計算結果:"+futureTask.get());
}
}
output:
開始執行任務
結束任務執行
計算結果:4950
Callable、Future和FutureTask簡介