【发布时间】:2017-10-13 22:23:09
【问题描述】:
ExecutorService有如下方法:
Future<?> submit(Runnable task)
但是既然Future的get方法总是会返回null,那么下面的签名不是更合适吗?
Future<Void> submit(Runnable task)
【问题讨论】:
标签: java multithreading asynchronous future executorservice
ExecutorService有如下方法:
Future<?> submit(Runnable task)
但是既然Future的get方法总是会返回null,那么下面的签名不是更合适吗?
Future<Void> submit(Runnable task)
【问题讨论】:
标签: java multithreading asynchronous future executorservice
注意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<?> 更合适。
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 起可用。所以我想这只是一个错误。
因为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 method() { return null; }
java.lang.Void(导入后缩写为Void),而不是void,和OP一样。其次,OP 并不要求没有返回值。