标准方案:用户按下按钮并启动大任务。 EventThread创建SwingWorker
来执行任务并继续生活。
现在,由于大任务是高度可并行化的,SwingWorker
线程所做的第一件事就是创建一堆工作线程并将其解决。
我的问题:是否允许工作线程调用SwingWorker#publish()
来触发GUI
更新,或者只允许SwingWorker
线程允许这样做?
谢谢, 卡斯滕
[编辑]一些伪代码使我的用例更清晰一些。问题基本上是:下面的代码是否正常?如果我遗漏waitForAllWorkerThreadsToFinish();
怎么办?
public class MySwingWorker extends SwingWorker {
class MyWorkerThread extends Runnable {
void run() {
while(!exitCondition) {
doSomeWork();
publish(progressUpdate);
reEvaluateExitCondition();
}
}
}
public Void doInBackground() {
createAndStartBunchOfMyWorkerThreads();
waitForAllWorkerThreadsToFinish();
}
void process(List<V> chunks) {
updateGuiWithProgress(chunks);
}
}
答案 0 :(得分:3)
一般来说,没有; publish()
旨在在后台线程上运行,后台线程本身必须同步来自子工作者的所有结果。幸运的是,在设计后台线程如何做到这一点时,你有相当大的自由度。例如,此example使用CountDownLatch
。
附录:waitForAllWorkerThreadsToFinish()
看起来像是CountDownLatch
的一个很好的用例。 MyWorkerThread
肯定不从publish()
以外的线程调用MySwingWorker
而不同步对任何共享数据的访问权限。 MyWorkerThread
可以使用invokeLater()
更新GUI,但订单不可靠。
附录:你问了一个非常实际的问题,
您是否有任何参考答案,[其他]工作者线程不允许使用
publish()
?
Memory Consistency Properties是一个很好的总结。实际上,您将在没有同步的情况下从多个线程调用publish()
。结果将无法预测。
答案 1 :(得分:2)
对于哪些线程可以调用SwingWorker#publish()
没有任何限制。