在編寫計算量大的應用程序時,我嘗試使用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