ExecutorCompletionService不适用于给定的参数

时间:2015-06-21 14:01:34

标签: java

在我的应用程序中,ExecutorCompletionService用于运行实现Callable的几个任务。当任务提交到ExecutorCompletionServer时,它会出现编译错误

The method submit(Callable<T>) in the type ExecutorCompletionService<T> is not applicable for the arguments (AbstractTask<capture#2-of ? extends Object>)  

这是我提交任务的方式。

List<AbstractTask<? extends Object>> taskList =new ArrayList<>();
        addTasks(new TaskA()); //TaskA,TaskB,TaskC are child classses of AbstractTask. addTasks() method add the child classes to taskList.
        addTasks(new TaskB());
        addTasks(new TaskC());
        List<Future<? extends Object>> futureList= new ArrayList<Future <? extends Object> >();

        final ExecutorService pool = Executors.newFixedThreadPool( TASK_SIZE );

        final ExecutorCompletionService<T> completionService = new ExecutorCompletionService<T >(pool);

        for ( AbstractTask<? extends Object>  callable : taskList) {
                futureList.add( completionService.submit(callable) );
        }  

这是addTaskMethod。

public void addTasks(AbstractTask<? extends Object> task){
            taskList.add(task);
        }

这是我的AbstractClass。

public abstract class AbstractTask<T extends Object> implements
        java.util.concurrent.Callable<T> {

    @Override
    public T call() throws Exception {

        return begin();
    }
    public abstract <B extends Object> B begin() throws RuntimeException ;

}

即使是以下方法&#39;提交()&#39;在java.util.concurrent.ExecutorCompletionService<V>接受争论

public Future<V> submit(Callable<V> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<V> f = newTaskFor(task);
    executor.execute(new QueueingFuture(f));
    return f;
}   

为什么我无法提交AbstractTask<? extends Object>?我的AbstractTask可以具有从Object扩展的任何值。 (如果我简单地删除for循环中的<? extends Object>,那么它就会被罚款。但是我的工具:Eclipse警告Type safety: The expression of type AbstractTask needs unchecked conversion to conform to Callable<T>。我该如何解决这个问题?)

编辑:这是TaskA类。

public class TaskA  extends AbstractTask<Object> {

    @SuppressWarnings("unchecked")
    @Override
    public java.lang.String begin() throws RuntimeException {
        System.out.println("Task A runs");
        return "A";
    }

}

2 个答案:

答案 0 :(得分:1)

您正在创建ExecutorCompletionService<T>。因此,这是一个ExecutorCompletionService,它接受Callable<T>的实例。

但您提交的是AbstractTask<? extends Object>的实例。 Callable<? extends Object>不是Callable<T>

A Callable<T>返回T的实例。Callable<? extends Object>返回一些未知类型,我们所知道的是类型扩展了Object。所以这基本上就像是想将未知物体放入碎纸机中。碎纸机只能撕碎纸张,而不能切碎任何物体。编译器阻止你这样做,因为它显然不会正常工作。

您需要ExecutorCompletionService<Object>

答案 1 :(得分:1)

在以下行中,我们正在创建ExecutorCompletionService<T>

的实例
final ExecutorCompletionService<T> completionService = new ExecutorCompletionService<T >(pool);

它只接受Callable<T>submit将返回Future<T>,当任务结束时,每个Future<T>将返回get类型的结果(使用T) {1}}。

如果我们在submit中检查ExecutorCompletionService方法的签名:

public Future<V> submit(Callable<V> task)

然后它指定类型变量V,以便所有可调用的类型V都相同。 IMO,Executor Completion Service将不允许提交Callable<? extends Object>类型的任务,因为它就像是说我的任务扩展Object,这意味着它几乎可以完成所有事情。因此,我们不能将未绑定的通配符与ECS一起使用,并且必须限制可能的结果。

在旁注上我相信Callable<? extends Object>Callable<?>是相同的。