JAVA線程池 submit方法返回值

JAVA線程池 submit方法返回值

AbstractExecutorService

 public abstract class AbstractExecutorService implements ExecutorService {
 
     // RunnableFuture 是用於獲取執行結果的,我們常用它的子類 FutureTask
     // 下面兩個 newTaskFor 方法用於將我們的任務包裝成 FutureTask 提交到線程池中執行
     protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
         return new FutureTask<T>(runnable, value);
     }
 
     protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
         return new FutureTask<T>(callable);
     }
 
     // 提交任務
     public Future<?> submit(Runnable task) {
         if (task == null) throw new NullPointerException();
         // 1. 將任務包裝成 FutureTask
         RunnableFuture<Void> ftask = newTaskFor(task, null);
         // 2. 交給執行器執行,execute 方法由具體的子類來實現
         // 前面也說了,FutureTask 間接實現了Runnable 接口。
         execute(ftask);
         return ftask;
     }
 
     public <T> Future<T> submit(Runnable task, T result) {
         if (task == null) throw new NullPointerException();
         // 1. 將任務包裝成 FutureTask
         RunnableFuture<T> ftask = newTaskFor(task, result);
         // 2. 交給執行器執行
         execute(ftask);
         return ftask;
     }
 
     public <T> Future<T> submit(Callable<T> task) {
         if (task == null) throw new NullPointerException();
         // 1. 將任務包裝成 FutureTask
         RunnableFuture<T> ftask = newTaskFor(task);
         // 2. 交給執行器執行
         execute(ftask);
         return ftask;
     }
 }

RunnableFuture

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

public class FutureTask<V> implements RunnableFuture<V> { 
     private volatile int state; 
     private static final int NEW = 0; //初始狀態 
     private static final int COMPLETING = 1; //結果計算完成或響應中斷到賦值給返回值之間的狀態。 
     private static final int NORMAL = 2; //任務正常完成,結果被set 
     private static final int EXCEPTIONAL = 3; //任務拋出異常 
     private static final int CANCELLED = 4; //任務已被取消 
     private static final int INTERRUPTING = 5; //線程中斷狀態被設置ture,但線程未響應中斷 
     private static final int INTERRUPTED = 6; //線程已被中斷 
 
     //將要執行的任務 
     private Callable<V> callable; //用於get()返回的結果,也可能是用於get()方法拋出的異常 
     private Object outcome; // non-volatile, protected by state reads/writes //執行callable的線程,調用FutureTask.run()方法通過CAS設置 
     private volatile Thread runner; //棧結構的等待隊列,該節點是棧中的最頂層節點。 
     private volatile WaitNode waiters; 
 
     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
    }
    
    protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }
    
    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }

    /**
     * @throws CancellationException {@inheritDoc}
     */
    public V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (unit == null)
            throw new NullPointerException();
        int s = state;
        if (s <= COMPLETING &&
            (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
            throw new TimeoutException();
        return report(s);
    }
    
    private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }
    
    public void run() {
         //保證callable任務只被運行一次
         if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread()))
             return;
         try {
             Callable < V > c = callable;
             if (c != null && state == NEW) {
                 V result;
                 boolean ran;
                 try { 
                     //執行任務,上面的例子我們可以看出,call()裏面可能是一個耗時的操作,不過這裏是同步的
                     result = c.call();
                     //上面的call()是同步的,只有上面的result有了結果纔會繼續執行
                     ran = true;
                 } catch (Throwable ex) {
                     result = null;
                     ran = false;
                     setException(ex);
                 }
                 if (ran)
                     //執行完了,設置result
                     set(result);
             }
         }
         finally {
             runner = null;
             int s = state;
             //判斷該任務是否正在響應中斷,如果中斷沒有完成,則等待中斷操作完成
             if (s >= INTERRUPTING)
                 handlePossibleCancellationInterrupt(s);
         }
    }
    ....
}

Excutor內部方法

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

Excutor內部類RunnableAdapter

    static final class RunnableAdapter<T> implements Callable<T> {
        final Runnable task;
        final T result;
        RunnableAdapter(Runnable task, T result) {
            this.task = task;
            this.result = result;
        }
        public T call() {
            task.run();
            return result;
        }
    }

爲什麼AbstractExecutorService中submit方法內部使用的是excute,但是卻有返回值

傳入的任務如果是實現Runnable接口的,會通過RunnableAdapter方式轉換成Callable

最終執行的是FutureTask中的run方法,結果賦值給Object outcome,通過get獲取,返回outcome.

參考:

併發編程(十二)—— Java 線程池 實現原理與源碼深度解析 之 submit 方法 (二)

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