天天看點

多線程:Callable與Future模式

在Java中,建立線程一般有兩種方式,一種是繼承Thread類,一種是實作Runnable接口。然而,這兩種方式的缺點是線上程任務執行結束後,無法擷取執行結果。我們一般隻能采用共享變量或共享存儲區以及線程通信的方式實作獲得任務結果的目的。

不過,Java中,也提供了使用Callable(康類躲)和Future來實作擷取任務結果的操作。Callable用來執行任務,産生結果,而Future用來獲得結果。

Future常用方法:

V get() :擷取異步執行的結果,如果沒有結果可用,此方法會阻塞直到異步計算完成。

V get(Long timeout , TimeUnit unit) :擷取異步執行結果,如果沒有結果可用,此方法會阻塞,但是會有時間限制,如果阻塞時間超過設定的timeout時間,該方法将抛出異常。

boolean isDone() :如果任務執行結束,無論是正常結束或是中途取消還是發生異常,都傳回true。

boolean isCanceller() :如果任務完成前被取消,則傳回true。

boolean cancel(boolean mayInterruptRunning) :

如果任務還沒開始,執行cancel(…)方法将傳回false;如果任務已經啟動,執行cancel(true)方法将以中斷執行此任務線程的方式來試圖停止任務,如果停止成功,傳回true;當任務已經啟動,執行cancel(false)方法将不會對正在執行的任務線程産生影響(讓線程正常執行到完成),此時傳回false;當任務已經完成,執行cancel(…)方法将傳回false。mayInterruptRunning參數表示是否中斷執行中的線程。

通過方法分析我們也知道實際上Future提供了3種功能:

(1)能夠中斷執行中的任務

(2)判斷任務是否執行完成

(3)擷取任務執行完成後額結果。

簡單的例子來體會使用Callable和Future來擷取任務結果的用法:

public class TestMain {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //可緩存線程池
        ExecutorService executor = Executors.newCachedThreadPool();
        Future<Integer> future = executor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("####AddNumberTask###call()");
                Thread.sleep(5000);
                return 5000;
            }
        });
        System.out.println(Thread.currentThread().getName() + "線程執行其他任務");
        // get() :擷取異步執行的結果,如果沒有結果可用,此方法會阻塞直到異步計算完成。
        Integer integer = future.get();
        System.out.println(integer);
        if(executor != null){
            executor.shutdown();
        }
    }
}
           

Future模式:

繼續閱讀