• 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方法
  • 相关阅读:
    easyui-lang-zh_CN.js导入后还是英文提示
    MongoDB的备份(mongodump)与恢复(mongorestore)
    mongodb windows下服务安装与卸载
    MongoDB 权限管理 用户名和密码的操作
    Super Hide IP 3.4.7.8允许您以匿名方式进行网上冲浪、 保持隐藏您的 IP 地址
    Delphi IDE下载全地址
    Delphi IDE下载全地址
    Delphi XE2及以后的版本编译后的程序大小问题
    Delphi XE2及以后的版本编译后的程序大小问题
    DevExpress VCL 一键安装工具
  • 原文地址:https://www.cnblogs.com/avalon-merlin/p/9198444.html
Copyright © 2020-2023  润新知