【问题标题】:Why does ExecutorService.submit(Runnable task) return Future<?> rather than Future<Void>?为什么 ExecutorService.submit(Runnable task) 返回 Future<?> 而不是 Future<Void>?
【发布时间】:2017-10-13 22:23:09
【问题描述】:

ExecutorService有如下方法:

Future<?> submit(Runnable task)

但是既然Futureget方法总是会返回null,那么下面的签名不是更合适吗?

Future&lt;Void&gt; submit(Runnable task)

【问题讨论】:

    标签: java multithreading asynchronous future executorservice


    【解决方案1】:

    注意Runnablerun 方法返回void 原语而不是Void 类型。出于这个原因,Future 不能有 Void 类型,解决方案是使其成为通配符。请注意,Future 来自 java 1.5,而Runnable 来自 1.0。由于遗留代码原因,他们不会更改run 的返回类型以符合Future

    【讨论】:

    • Future&lt;Void&gt; 的 get 方法将始终返回 null,这正是在这种情况下所要求的。 Future&lt;?&gt; 可以返回任何对象,而实际上在这种特殊情况下它总是返回 null,如 submit 方法的 javadoc 中所述。所以Future&lt;Void&gt; 在这里是正确的选择。类似地,如果run 会返回double,则Future&lt;Double&gt; 将比Future&lt;?&gt; 更合适。
    【解决方案2】:

    jdk 1.8里面的submit方法实现用void,jdk1.6是Object。我的理解是用void更合适,所以jdk1.7/1.8改了。只支持接口不变它

     public Future<?> submit(Runnable task) {
            if (task == null) throw new NullPointerException();
            RunnableFuture<Void> ftask = newTaskFor(task, null);
            execute(ftask);
            return ftask;
        }
    

    在 JDK 1.6 中

     public Future<?> submit(Runnable task) {
           if (task == null) throw new NullPointerException();
           RunnableFuture<Object> ftask = newTaskFor(task, null);
           execute(ftask);
            return ftask;
       }
    

    【讨论】:

    • 是的,我知道他们不想在之后更改界面。但为什么它首先被定义为它的方式呢? Void 类型自 Java 1.1 起可用。所以我想这只是一个错误。
    【解决方案3】:

    因为ExecutorServiceFuture 接口是为了从另一个线程获取返回数据而创建的,而不仅仅是为了运行它。 Future&lt;Void&gt; submit(Runnable task)new Thread(runnable).start() 的作用相同,null 的返回在某些情况下是有意义的。

    编辑: 认为您需要在 20 分钟后关闭线程。当你有一个返回值 void 时,你会怎么做?

    Future<Void> future = execService.submit(operation);
    execService.shutdown();
    opResult = future.get(20, TimeUnit.MINUTES);
    

    此代码必须给出错误,因为future 没有返回。但是如果它返回一个空值,execService 控制器对象将知道shutdown 发生了。或者如果它在 20 分钟内没有返回任何东西,则可以使用 execService.shutdownNow()

    【讨论】:

    • 如果是Future&lt;Void&gt;,它的工作方式与现在完全相同。
    • 如何从调用方法返回 Void ?
    • Void method() { return null; }
    • return null 与 void 签名方法不同。 Op 要求没有返回值
    • 首先,我的意思是java.lang.Void(导入后缩写为Void),而不是void,和OP一样。其次,OP 并不要求没有返回值。
    猜你喜欢
    • 1970-01-01
    • 2019-10-08
    • 2020-08-15
    • 2015-09-22
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多