java中FutureTask的使用



java中FutureTask的使用

FutureTask簡介

FutureTask是java 5引入的一個類,從名字可以看出來FutureTask既是一個Future,又是一個Task。

我們看下FutureTask的定義:

public class FutureTask<V> implements RunnableFuture<V> {
    ...
}
public interface RunnableFuture<V> extends Runnable, Future<V> {
    /** * Sets this Future to the result of its computation * unless it has been cancelled. */
    void run();
}

FutureTask實現了RunnableFuture接口,RunnableFuture接口是Runnable和Future的綜合體。

作為一個Future,FutureTask可以執行異步計算,可以查看異步程序是否執行完畢,並且可以開始和取消程序,並取得程序最終的執行結果。

除此之外,FutureTask還提供了一個runAndReset()的方法, 該方法可以運行task並且重置Future的狀態。

Callable和Runnable的轉換

我們知道Callable是有返回值的,而Runnable是沒有返回值的。
Executors提供了很多有用的方法,將Runnable轉換為Callable:

    public static <T> Callable<T> callable(Runnable task, T result) {
        if (task == null)
            throw new NullPointerException();
        return new RunnableAdapter<T>(task, result);
    }

FutureTask內部包含一個Callable,並且可以接受Callable和Runnable作為構造函數:

    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
    }

它的內部就是調用了Executors.callable(runnable, result);方法進行轉換的。

以Runnable運行

既然是一個Runnable,那么FutureTask就可以以線程的方式執行,我們來看一個例子:

@Test
    public void convertRunnableToCallable() throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
               log.info("inside callable future task ...");
                return 0;
            }
        });

        Thread thread= new Thread(futureTask);
        thread.start();
        log.info(futureTask.get().toString());
    }

上面例子是以單個線程來執行的,同樣我們也可以將FutureTask提交給線程池來執行:

    @Test
    public void workWithExecutorService() throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                log.info("inside futureTask");
                return 1;
            }
        });
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.submit(futureTask);
        executor.shutdown();
        log.info(futureTask.get().toString());
    }

本文的例子可參考https://github.com/ddean2009/learn-java-concurrency/tree/master/futureTask

更多教程請參考 flydean的博客


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM