Future <t>与在Java Executor Service中扩展Task <t>的Class不兼容

时间:2017-10-26 18:33:58

标签: java concurrency future executorservice

我的班级DownloadTask扩展了javafx.concurrent.Task<Boolean>

将我的任务提交给ExecutorService后,我尝试将结果分配给Future<Boolean>类型的变量。但是,IDE警告我,我的实例化对象具有泛型类型<capture<?>>,我不知道为什么。

我的班级DownloadTask

import javafx.concurrent.Task;

private class DownloadTask extends Task<Boolean>{
    public DownloadTask() {}

    @Override
    protected Boolean call() throws Exception {
         return true;
    }
}

我如何管理线程池:

ExecutorService executor = Executors.newFixedThreadPool(10);
ArrayList<Future<Boolean>> resultList = new ArrayList<>();

for (ScheduleRow scheduleRow : queArray) {
    DownloadTask downloadTask = new DownloadTask();

    Future<Boolean> result = executor.submit(downloadTask); //incompatible types

    resultList.add(result);
}

executor.shutdown();

3 个答案:

答案 0 :(得分:1)

简短回答

要解决该警告,您可以添加类型信息以启用类型推断:

Future<Boolean> result = executor.submit(downloadTask, true);

但请注意,对于result变量,Future的{​​{1}}方法会在成功完成后返回给定的 true ,因为get被解释为DownloadTask,但不会产生结果。正如Mike Strobel所说,更好的方法是从Runnable本身获得正确的结果,因为它也是DownloadTask

Future<Boolean>

答案很长

正如Andy Turner所说,executor.submit(downloadTask); resultList.add(downloadTask); 的继承类型是javafx.concurrent.Task(因为它扩展Runnable实施FutureTask)。

将此传递给RunnableFuture的{​​{1}}方法会产生Future<?> submit(Runnable task)结果,IDE会抛出那个讨厌的ExecutorService

但是,您不需要特定于javafx的Future<?>Future<capture<?>>可以正常工作,因为ExecutorServicejava.util.concurrent.ExecutorService的子类。

要修复类型推断,您可以使用DownloadTask的通用FutureTask方法。由于它是一个简单的布尔值,您可以依靠自动装箱:

<T> Future<T> submit(Runnable task, T result)

问题是,对于java.util.concurrent.ExecutorService变量,Future<Boolean> result = executor.submit(downloadTask, true); 的get方法将在成功完成后返回给定的 true 。在您的示例中,生成的result上的Future方法将始终返回get。这是因为它被解释为Future,不会产生结果。正如Mike Strobel所说,更好的方法是从DownloadTask本身获得正确的结果,因为它也是一个未来:

null

答案 1 :(得分:0)

根据javafx.concurrent.Task的Javadoc,Task实现了Runnable,而不是Callable<T>

因此,当您将其提交给ExecutorService时,会将其视为不返回值的内容,因此生成的后续内容为Future<?>

使用特定于javafx的ExecutorService(不知道是否有一个专门用于Task);或者让您的班级实现Callable<Boolean>

答案 2 :(得分:0)

你真的不需要对submit的结果做任何事情;您的DownloadTask已经已经一个Future<Boolean>,当它运行时,它将设置自己的结果。 Future<?>返回的submit无论如何都无法转发您的任务结果,因为它只是将其视为Runnable而不会产生值。

只需改变一下:

Future<Boolean> result = executor.submit(downloadTask);
resultList.add(result);

对此:

executor.submit(downloadTask);
resultList.add(downloadTask);