java - 我的自定义事件应该在 GUI EDT 还是 "home-grown"EDT 上触发

标签 java multithreading swing listeners event-dispatch-thread

我正在开发一个项目,该项目需要进行一些密集的数学计算(矩阵、 vector 数组等),因此我很自然地将工作分成多个作业,并将它们提交给 CompletionService 以并行执行工作.

每个作业对象都可以在作业开始、结束、进行和/或失败时触发事件来通知应用程序。

目前,每个作业都会接收整个事件监听器列表的句柄,并简单地进行迭代,将事件对象传递给每个作业(在同一线程中)。这对我来说不太合适,所以我想了解其他人使用自定义事件/监听器执行此类操作的经验。

我应该将事件发送到 GUI 线程吗?一些监听器可能与 GUI 相关,也可能不相关,我不想强​​迫我的代码的用户必须手动将其事件发送到 GUI 线程,如下所示:

public class MyFooEventListener implements FooEventListener {
    public void notifyJobStarted(FooEvent evt) {
        // I want to avoid having users of my library write the following, right?
        SwingUtilities.invokeLater(new Runnable(){
            // update GUI here.
        });
    }
}

我不介意编写自己的 EventQueue,因为这是学校的一个研究项目,我认为这将是一个很好的并发练习。只是想弄清楚实现事件驱动系统的“正确”方法是什么,如何正确触发事件等。也非常感谢文章/教程和指南的链接。

谢谢!

编辑:

我的事件模型有多种事件类型,例如 JobStartedEventJobEndedEventJobProgressEvent 等。这是一个不好的方法吗?我是否应该有单一事件类型?如果是,如何将并非所有事件共有的信息传递给监听器?示例:我想为进度事件传递 [0-1] 范围内的 double 值,但这不适用于像 JobFailureEvent 这样的事件。处理这个问题的最佳方法是什么?

我可以将额外的信息放在“源”对象本身中,但我的源对象是作业对象本身,并且“泄漏”对作业对象的引用并不适合我,尤其是当它是运行:

FooJob jobObject = (FooJob)event.getSource();
int progressPercent = jobObject.getCurrentProgress() * 100;
progressLabel.setText(progressPercent + "%");

最佳答案

没有。在任何需要引发事件的线程上发出事件,并将其留给子系统的用户来决定他们希望如何处理它们。如果他们希望将结果发送给 GUI,那很好,如果不想,他们可以做任何他们想做的事情,例如。将它们排队到另一个线程。只需记录“事件在内部线程上引发,事件处理程序不得阻塞”。

正如您所说,任何其他事情都会对用户施加他们可能不想要的限制。

关于java - 我的自定义事件应该在 GUI EDT 还是 "home-grown"EDT 上触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12940530/

相关文章:

java - 将字节数组转换为BigInteger

java - 识别能够更新 UI 组件的线程

java - 如何清空此面板并添加新面板

java - 如何获取类层次结构中较低层的类的对象

java - 消息重新传递 ibm mq

java - 为什么 SwingUtilities.invokeLater 会抛出 NullPointerException?

java - 复合 PK 字段的分离标准?

java - Java中多维ArrayList添加元素

java - 我怎样才能在 swt 中放置一个小部件并在同一个地方再次创建该小部件?

java - 检测文件在 Java 中重新打开