execute和submit的区别

execute方法位于接口Executor中。

1 void execute(Runnable command);

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     }
21 

根据源码可以看到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     }
16 

看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     }

 

posted @ 2018-08-21 14:07  浅滩沙洲  阅读(286)  评论(0编辑  收藏  举报