獲取子線程的執行結果

創建線程有哪幾種方式

  • 繼承Thread類(Thread類也是實現Runnable接口);
public
class Thread implements Runnable {
  • 實現Runnable接口;
  • 通過線程池創建線程池;
  • 實現Callable接口與ExecutorService結合使用

因爲Java的類是單繼承,接口可以多實現。所以在創建子任務的時候,更多的是選擇實現接口。線程池的出現爲了讓線程可以很好的複用,減少系統開銷(線程的啓動、銷燬等過程是比較複雜的),同時也統一把線程管理起來。

Runnable不足?

現Runnable接口中的run()方法:

public abstract void run();

通過源碼中的run方法可以看出,run方法沒有返回值。如果我們需要接受子線程返回結果,此時該接口已經不滿足我們的需求了。那麼怎麼接受子線程返回的結果呢?此時就需要通過Callable接口創建線程了。同樣的先看看過Callable接口中的方法定義

Callable接口中的call()方法

 V call() throws Exception;

和run()對比,可以看出該方法支持返回值,支持向上拋出異常。

Callable接口的簡單實例

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> future = executorService.submit(new Task());//submit結果
        String result = future.get();//取出子線程運行結果
        System.out.println("子任務的執行結果:"+result);//子任務的執行結果:1995-01-01
        executorService.shutdown();
    }

    private static class Task implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "1995-01-01";
        }
    }

FutureTask獲取結果

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        //通過Callable實例構建FutureTask實例
        FutureTask<String> futureTask = new FutureTask<>(new Task());
        //提交任務到線程池
        executorService.execute(futureTask);
        //取出子線程運行結果
        String result = futureTask.get();
        System.out.println("子任務的執行結果:" + result);//子任務的執行結果:1995-01-02
    }

    private static class Task implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "1995-01-02";
        }
    }

Future接口中方法
在這裏插入圖片描述
其實根據命名,已經可以推測出這些方法的作用了,下面主要記錄一些注意點

  • get():獲取Callable接口返回的結果,假設主線程調用了get()方法,但是此時子線程還沒有執行完畢(即還沒有返回結果),此時主線程會被阻塞,知道call()方法返回了結果。
  • get(long timeout, TimeUnit unit):在get()的基礎上加上超時時間;
  • isDone():判斷子線程是否執行完畢;
  • cancel(boolean mayInterruptIfRunning):取消線程

取消線程坑時可能遇到的幾種情況
1.線程還沒有執行:返回true

2.線程已經執行完畢或者取消了,返回false;

3.線程已經開始執行了,此時根據設置的mayInterruptIfRunning來判斷是否直接取消任務。mayInterruptIfRunning爲ture適用於子任務有邏輯處理中斷。false適用於子線程沒有能力處理中斷;需求是需要等待已經開始的線程執行完畢。

FutureTask
在這裏插入圖片描述
FutureTask:實現了Runnable和Future接口,表示異步計算的結果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章