invokeAll()不愿意接受Collection <Callable >
我不明白为什么这段代码不能编译
ExecutorService executor = new ScheduledThreadPoolExecutor(threads); class DocFeeder implements Callable {....} ... List list = new LinkedList(); list.add(new DocFeeder(1)); ... executor.invokeAll(list);
错误消息是:
The method invokeAll(Collection<Callable>) in the type ExecutorService is not applicable for the arguments (List)
list
是DocFeeder
的Collection
,它实现了Callable
– 发生了什么?!
只是为了扩大saua的答案……
在Java 5中,该方法被声明为:
invokeAll(Collection> tasks)
在Java 6中,该方法声明为:
invokeAll(Collection extends Callable> tasks)
通配符的区别非常重要 – 因为List
是一个Collection extends Callable
Collection extends Callable
但它不是 Collection
。 考虑一下这种方法会发生什么:
public void addSomething(Collection> collection) { collection.add(new SomeCallable()); }
这是合法的 – 但如果您可以使用List
调用addSomething
,那将是非常糟糕的,因为它会尝试将非DocFeeder添加到列表中。
因此,如果您遇到Java 5,则需要从List
创建List
。
该代码与Java 6编译完美,但无法使用Java 5编译
Foo.java:9:找不到符号 symbol:方法invokeAll(java.util.List) location:interface java.util.concurrent.ExecutorService executor.invokeAll(列表); ^ 1错误
但是更改list
如下:
Collection> list = new LinkedList>();
使其适用于Java 5和Java 6。
感谢详细解答,但它仍然让我感到困惑–Callable是一个接口,所以实际上,Jon的答案中的“addSomething”函数应该没问题(不仅合法,而且合理) – 因为,这就是接口的全部要点 – 只要您遵守一些初步协议,我就不关心您要添加到列表中的对象。 imo,你提出的问题应该在不同的范围内解决。
除此之外,事实仍然是代码没有编译 – 它应该……
Collection> list = new LinkedList>();
- ExecutorService与Casual Thread Spawner
- ExecutorService的shutdown()不会等到所有线程都完成
- 在webapp中正常关闭ExecutorService?
- 如何等待一个产生它自己的线程的线程?
- 如何为CompletableFuture :: supplyAsync选择Executor
- 在ThreadPoolExecutor中使用InheritableThreadLocal – 或者 – 不重用线程的ThreadPoolExecutor
- Java执行官:如何停止提交的任务?
- 一旦我的线程中断,我怎么能中断RestTemplate调用?
- Java Executor服务线程池