允许哪些线程调用SwingWorker#publish?

时间:2011-06-29 05:33:24

标签: java multithreading swing swingworker

标准方案:用户按下按钮并启动大任务。 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);
  }
}

2 个答案:

答案 0 :(得分:3)

一般来说,没有; publish()旨在在后台线程上运行,后台线程本身必须同步来自子工作者的所有结果。幸运的是,在设计后台线程如何做到这一点时,你有相当大的自由度。例如,此example使用CountDownLatch

附录:waitForAllWorkerThreadsToFinish()看起来像是CountDownLatch的一个很好的用例。 MyWorkerThread肯定publish()以外的线程调用MySwingWorker而不同步对任何共享数据的访问权限。 MyWorkerThread 可以使用invokeLater() 更新GUI,但订单不可靠。

附录:你问了一个非常实际的问题,

  

您是否有任何参考答案,[其他]工作者线程不允许使用publish()

Memory Consistency Properties是一个很好的总结。实际上,您将在没有同步的情况下从多个线程调用publish()。结果将无法预测。

答案 1 :(得分:2)

对于哪些线程可以调用SwingWorker#publish()没有任何限制。