在编写计算量大的应用程序时,我尝试使用SwingWorker类将负载分散到多个CPU核心。然而,这个类别的行为证明有点奇怪:似乎只有一个核心被利用。如何正确地扩展FutureTask
当搜索互联网,我发现了一个很好的回答这个网站上(见Swingworker instances not running concurrently,通过user268396答案),这 - 除了问题的原因 - 也提到了一个可能的解决方案:
你可以做些什么来解决这个问题是使用一个ExecutorService并在其上发布FutureTasks。这些将提供99%的SwingWorker API (SwingWorker是FutureTask衍生产品),您所要做的就是正确设置 Executor。
作为一名Java初学者,我不完全确定如何正确地做到这一点。不仅需要将一些初始数据传递给FutureTask对象,还需要像SwingWorker一样返回结果。因此,任何示例代码都将非常感谢。
NVX
====================编辑====================
在执行FutureTask that implements Callable中提到的简单而优雅的解决方案后,出现了另一个问题。如果我使用ExecutorService
来创建单独的线程,在线程完成运行后如何执行特定的代码?我试图覆盖FutureTask
对象的完成()(请参阅下面的代码),但我想应该在应用程序的事件分派线程中完成“显示结果”位(或任何与GUI相关的东西) (美东时间)。因此:如何将可运行代码提交给EDT?
package multicoretest;
import java.util.concurrent.*;
public class MultiCoreTest {
static int coresToBeUsed = 4;
static Future[] futures = new Future[coresToBeUsed];
public static void main(String[] args) {
ExecutorService execSvc = Executors.newFixedThreadPool(coresToBeUsed);
for (int i = 0; i < coresToBeUsed; i++) {
futures[i] = execSvc.submit(new Worker(i));
}
execSvc.shutdown();
// I do not want to block the thread (so that users can
// e.g. terminate the computation via GUI)
//execSvc.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
static class Worker implements Callable<String> {
private final FutureTask<String> futureTask;
private final int workerIdx;
public Worker(int idx) {
workerIdx = idx;
futureTask = new FutureTask<String>(this) {
@Override
protected void done() {
Runnable r = new Runnable() {
@Override
public void run() {
showResults(workerIdx);
}
};
r.run(); // Does not work => how do I submit the runnable
// to the application's event dispatch thread?
}
};
}
@Override
public String call() throws Exception {
String s = "";
for (int i = 0; i < 2e4; i++) {
s += String.valueOf(i) + " ";
}
return s;
}
final String get() throws InterruptedException, ExecutionException {
return futureTask.get();
}
void showResults(int idx) {
try {
System.out.println("Worker " + idx + ":" +
(String)futures[idx].get());
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
}
检查是否有帮助。检查[这里] [1] [1]:http://stackoverflow.com/questions/1808776/extending-futuretask-how-to-handle-cancel – chiru 2013-02-27 13:21:39
谢谢你,我会看它。在此期间,我在这里找到了[主题](http://stackoverflow.com/questions/1468598/futuretask-that-implements-callable),这似乎是实现我所需要的另一种方式(即使我需要创建一个额外的抽象类)。 – nvx 2013-02-27 14:31:44