• 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     }
  • 相关阅读:
    YL杯超级篮球赛 (Standard IO)
    Window (Standard IO)
    toj1026 Network 双连通分量
    poj3177 Redundant Paths 双连通分量
    poj1144 Network 双连通分量
    bzoj1269
    bzoj1800
    CF911D
    CF910C
    CF910B
  • 原文地址:https://www.cnblogs.com/yuandluck/p/9511000.html
Copyright © 2020-2023  润新知