Yos*_*ale 8 java callable executorservice
我无法理解为什么这段代码不能编译
ExecutorService executor = new ScheduledThreadPoolExecutor(threads);
class DocFeeder implements Callable<Boolean> {....}
...
List<DocFeeder> list = new LinkedList<DocFeeder>();
list.add(new DocFeeder(1));
...
executor.invokeAll(list);
Run Code Online (Sandbox Code Playgroud)
错误消息是:
The method invokeAll(Collection<Callable<T>>) in the type ExecutorService is
not applicable for the arguments (List<DocFeeder>)
Run Code Online (Sandbox Code Playgroud)
list是Collection的DocFeeder,它实现了Callable<Boolean>-这是怎么回事?
Jon*_*eet 18
只是为了扩大saua的答案......
在Java 5中,该方法被声明为:
invokeAll(Collection<Callable<T>> tasks)
Run Code Online (Sandbox Code Playgroud)
在Java 6中,该方法声明为:
invokeAll(Collection<? extends Callable<T>> tasks)
Run Code Online (Sandbox Code Playgroud)
通配符的差异非常重要 - 因为它List<DocFeeder> 是一个Collection<? extends Callable<T>>但它不是一个Collection<Callable<T>>.考虑一下这种方法会发生什么:
public void addSomething(Collection<Callable<Boolean>> collection)
{
collection.add(new SomeCallable<Boolean>());
}
Run Code Online (Sandbox Code Playgroud)
这是合法的 - 但如果您可以addSomething使用a 来调用List<DocFeeder>它会非常糟糕,因为它会尝试将非DocFeeder添加到列表中.
所以,如果你遇到Java 5,你需要创建一个List<Callable<Boolean>>来自你的List<DocFeeder>.
该代码与Java 6编译完美,但无法使用Java 5编译
Foo.java:9: cannot find symbol
symbol : method invokeAll(java.util.List)
location: interface java.util.concurrent.ExecutorService
executor.invokeAll(list);
^
1 error
但改变list这样:
Collection<Callable<Boolean>> list = new LinkedList<Callable<Boolean>>();
Run Code Online (Sandbox Code Playgroud)
使其适用于Java 5和Java 6.