2011-06-29 52 views
3

标准方案:用户按下按钮并启动大任务。 EventThread创建SwingWorker来执行任务,并终身实现。允许哪些线程调用SwingWorker#publish?

现在,由于大任务是高度可并行化的,因此线程所做的第一件事就是创建一堆工作线程和工作区。

我的问题:工作线程是否允许调用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); 
    } 
} 

回答

3

一般来说,没有; publish()旨在运行在后台线程上,后台线程必须自己同步所有来自辅助工作者的结果。幸运的是,您在设计后台线程如何执行此操作方面拥有相当大的自由度。例如,这个example使用CountDownLatch

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

附录:你问的很现实的问题,

你有你的答案任何引用,即[其他]工作线程不允许使用publish()

Memory Consistency Properties是一个很好的总结。实际上,您将从多个线程中调用publish()而不同步。结果将是不可预测的。

+0

感谢您的回答。我认为CountDownLatch并不适合我的情况,因为工作线程需要经常更新GUI以显示进度,而不仅仅是在完成时。 理想情况下,他们想调用publish(),并在GUI中显示一些进度信息。 – Carsten

+0

这可能有助于更新您的问题,更详细地介绍工人相互依赖的性质。 – trashgod

+0

公平点。添加了我的用例的伪代码示例。 – Carsten

2

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

+0

你有参考或其他信息来支持它吗? – Carsten

+0

不,我刚刚浏览了Sun的JDK 1.6中的源代码。代码不会对可以调用publish()的主题施加任何限制,主要作用(向sun.swing.AccumulativeRunnable添加块)是一个同步操作。这仅适用于Sun的JVM,但在另一个JVM中使此操作不是Threadsafe将是特有的。 – Bringer128

相关问题