1. 程式人生 > >Callable、Future和FutureTask簡介

Callable、Future和FutureTask簡介

線程池 異步 rgs lex dem 抽象類 及其 down ide

1. RunnableCallable<v>Future及其實現類FutureTask對比

RunnableCallable<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

FutureTaskRunnableFuture<v>的實現類,而RunnableFuture<V>RunnableFuture的子接口(接口可以多繼承)。**註意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簡介