1. 程式人生 > >ExecutorService實現獲取執行緒返回值

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取出返回值。