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 }