execute和submit的區別


execute方法位於接口Executor中。

1     void execute(Runnable command);
execute

submit方法位於AbstractExecutorService中。

 1     public Future<?> submit(Runnable task) {
 2         if (task == null) throw new NullPointerException();
 3         RunnableFuture<Void> ftask = newTaskFor(task, null);
 4         execute(ftask);
 5         return ftask;
 6     }
 7 
 8     public <T> Future<T> submit(Runnable task, T result) {
 9         if (task == null) throw new NullPointerException();
10         RunnableFuture<T> ftask = newTaskFor(task, result);
11         execute(ftask);
12         return ftask;
13     }
14 
15     public <T> Future<T> submit(Callable<T> task) {
16         if (task == null) throw new NullPointerException();
17         RunnableFuture<T> ftask = newTaskFor(task);
18         execute(ftask);
19         return ftask;
20     }
submit

根據源碼可以看到execute僅可以接受Runnable類型,而submit重載了三個方法,參數可以是Runnable類型的接口、Runnable類型接口加泛型result以及Callable類型的接口。

從上面的方法也可以看出實際上如果用Runnable類型的接口也是可以有返回值的。

傳遞Runnable類型接口加result會被進一步封裝,在Executors這個類里面有個內部類RunnableAdapter實現了Callable接口。

 1     private static final class RunnableAdapter<T> implements Callable<T> {
 2         private final Runnable task;
 3         private final T result;
 4         RunnableAdapter(Runnable task, T result) {
 5             this.task = task;
 6             this.result = result;
 7         }
 8         public T call() {
 9             task.run();
10             return result;
11         }
12         public String toString() {
13             return super.toString() + "[Wrapped task = " + task + "]";
14         }
15     }
RunnableAdapter

看submit方法可以看出,submit最終也是在調用execute方法,無論是Runnable還是Callable類型接口,都會被封裝成FutureTask繼續執行。

總結:如果使用submit方法提交,會進一步封裝成FutureTask,執行execute方法,在FutureTask里面重寫的run方法里面調用Callable接口的call方法。

 1     public void run() {
 2         if (state != NEW ||
 3             !RUNNER.compareAndSet(this, null, Thread.currentThread()))
 4             return;
 5         try {
 6             Callable<V> c = callable;
 7             if (c != null && state == NEW) {
 8                 V result;
 9                 boolean ran;
10                 try {
11                     result = c.call();
12                     ran = true;
13                 } catch (Throwable ex) {
14                     result = null;
15                     ran = false;
16                     setException(ex);
17                 }
18                 if (ran)
19                     set(result);
20             }
21         } finally {
22             // runner must be non-null until state is settled to
23             // prevent concurrent calls to run()
24             runner = null;
25             // state must be re-read after nulling runner to prevent
26             // leaked interrupts
27             int s = state;
28             if (s >= INTERRUPTING)
29                 handlePossibleCancellationInterrupt(s);
30         }
31     }
FutureTask Run方法

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM