【问题标题】:Getting Future with correct type from ExecutorService using SwingWorker runnables使用 SwingWorker 可运行对象从 ExecutorService 获取正确类型的 Future
【发布时间】:2016-11-04 04:21:34
【问题描述】:

我想提交一些 SwingWorkers 给 ExecutorService,然后从他们那里获取 Futures 以便稍后查看他们是否完成以及结果如何。

但是,当我想要Future<Integer> 时,ExecutorService 的提交方法只会返回Future<?>

所以,问题:

  • 我是否正确扩展 SwingWorker?第一个泛型类型是 SwingWorker 上的 get() 返回的,所以我猜这也是 Future get() 方法将返回的。

  • SwingWorker 是不是用错了? (试图阅读这个问题,我看到大多数人将 Callables 提交给 ExecutorService)如果是这样,什么会更好,转换它的最佳方法是什么? (我对 SwingWorker 的实际扩展比这个例子更复杂,并且更新了 GUI 等)。我开始尝试在一个新类中实现 Callable,但我不确定如何实现发布/处理过程(没有双关语)。

重现问题的一些示例代码:

SwingWorker 扩展

import javax.swing.SwingWorker;

public class Worker extends SwingWorker<Integer, Void>
{
    public Worker ()
    {

    }

    @Override
    public Integer doInBackground()
    {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return 1;
    }

    @Override
    public void done()
    {
        System.out.println("done\n");
    }
}

Main - executor.submit(w) 部分给出编译错误:

Type mismatch: cannot convert from Future<capture#1-of ?> to Future<Integer>

并询问我是否想将 future 类型更改为 Future&lt;?&gt; 或将 executor.submit(w) 部分转换为 Future&lt;Integer&gt;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main
{
    public static void main (String[] args)
    {
        ExecutorService executor = Executors.newFixedThreadPool(2);

        Worker w = new Worker();
        Future<Integer> future = executor.submit(w);
    }
}

【问题讨论】:

    标签: java multithreading swing executorservice swingworker


    【解决方案1】:

    您可能希望使用submit() 的这种变体来明确结果类型:

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

    正如here 所讨论的,submit()result 没有任何作用。 “任务成功完成后,调用future.get()会返回你传入的结果。”请注意result 的类型与SwingWorker 结果类型T 的类型相匹配。

    代码:

    Integer i = 42;
    Future<Integer> future = executor.submit(w, i);
    System.out.println(future.get());
    

    控制台:

    42
    done
    

    在实际程序的更大范围内,您需要在 EDT 上 publish() 中间结果和 process() 它们。

    【讨论】:

    • 这是否意味着无法检索 SwingWorker 的 doInBackground() 的结果?
    • 谢谢,我没有意识到 SwingWorker 本身有一个 Future。所以现在我要执行 executor.execute(w) 并将所有 w 放在一个地图中以便稍后查看它们。如果有人想知道 SwingWorker 的实际工作原理,我在这里找到了源代码 grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…
    • 很高兴它有帮助。我想说SwingWorker 是一个 Future&lt;T&gt;,还有一个RunnableRunnableFuture&lt;T&gt;。另见Waiting for multiple SwingWorkers
    猜你喜欢
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-21
    • 2022-01-27
    相关资源
    最近更新 更多