ExecutorService實現獲取線程返回值

什麼是ExecutorService?

ExecutorService是java.util.concurrent包中的一個線程池實現接口。其有兩個實現類:ThreadPoolExecutor 和 ScheduledThreadPoolExecutor。分別用來實現普通線程池和延遲任務線程池。普通線程池通過配置線程池大小,能有效管理線程的調度,在執行大量異步線程時提高程序的性能。延遲任務線程池可控制在給定多長的延遲後執行線程。想要實現獲取線程的返回值,可以通過ThreadPoolExecutor及其子類管理線程。

實現帶返回值的Callable子類

創建一個線程類實現Callable接口,重寫call方法,其中call方法相當於Thread子類中的run方法。其內容為線程運行時所執行的業務。

ThreadWithCallable.java

package thread;

import java.util.concurrent.Callable;

/**
 *  一個包含返回值的線程類
 * @author xiezd 2018-01-14 21:40
 *
 */
public class ThreadWithCallback implements Callable{
    private int number;
    public ThreadWithCallback(int number){
        this.number = number;
    }
    //相當於Thread的run方法
    @Override
    public Object call() throws Exception {
        long begin = System.currentTimeMillis();
        int index = (int)(Math.random() * 99999999);
        int result = number;
        //隨便寫的
        for (int i = 1; i < index; i++) {
            result = (result / i ) * index;
        }
        long end = System.currentTimeMillis();
        return "計算數值為" + number + "的線程,花費:" + (end - begin) + "毫秒。";
    }
}

創建線程池測試

編寫一個測試類:

1.通過Excutors工廠類獲取一個固定大小的線程池對象。
2.調用線程池對象的submit方法,參數為一個線程對象,返回值為Future對象。
3.調用Future對象的get方法獲取線程返回值。
4.關閉線程池。

App.java

package thread;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @author xiezd 2018-01-14 21:49
 */
public class App {
    public static void main(String[] args) {
        ExecutorService executors = Executors.newFixedThreadPool(10);
        try {
            /* 啟動線程時會返回一個Future對象。
             * 可以通過future對象獲取現成的返回值。
             * 在執行future.get()時,主線程會堵塞,直至當前future線程返回結果。
             */
            Future future1 = executors.submit(new ThreadWithCallback(20));
            Future future2 = executors.submit(new ThreadWithCallback(30));
            System.out.println(future1.get());
            System.out.println(future2.get());

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }finally {
            executors.shutdown();
        }
    }
}

註:在future調用get方法時,主線程會阻塞(sè),直到該線程執行完畢返回對象瞭隻有才繼續運行。

如果要執行n個線程,可以把future放入Set集合中,在所有線程都啟動完畢後,遍歷Set取出返回值。

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: