为啥 ExecutorService.submit(Runnable task) 返回 Future<?> 而不是 Future<Void>?
Posted
技术标签:
【中文标题】为啥 ExecutorService.submit(Runnable task) 返回 Future<?> 而不是 Future<Void>?【英文标题】: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)
但是既然Future
的get
方法总是会返回null
,那么下面的签名不是更合适吗?
Future<Void> submit(Runnable task)
【问题讨论】:
【参考方案1】:注意Runnable
的run
方法返回void
原语而不是Void
类型。出于这个原因,Future
不能有 Void
类型,解决方案是使其成为通配符。请注意,Future
来自 java 1.5,而Runnable
来自 1.0。由于遗留代码原因,他们不会更改run
的返回类型以符合Future
。
【讨论】:
Future<Void>
的 get 方法将始终返回 null
,这正是在这种情况下所要求的。 Future<?>
可以返回任何对象,而实际上在这种特殊情况下它总是返回 null
,如 submit
方法的 javadoc 中所述。所以Future<Void>
在这里是正确的选择。类似地,如果run
会返回double
,则Future<Double>
将比Future<?>
更合适。【参考方案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】:
因为ExecutorService
的Future
接口是为了从另一个线程获取返回数据而创建的,而不仅仅是为了运行它。
Future<Void> 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<Void>
,它的工作方式与现在完全相同。
如何从调用方法返回 Void ?
Void method() return null;
return null 与 void 签名方法不同。 Op 要求没有返回值
首先,我的意思是java.lang.Void
(导入后缩写为Void
),而不是void
,和OP一样。其次,OP 并不要求没有返回值。以上是关于为啥 ExecutorService.submit(Runnable task) 返回 Future<?> 而不是 Future<Void>?的主要内容,如果未能解决你的问题,请参考以下文章
ExecutorService.submit()与Executor.execute()的区别