【问题标题】:How can I pass an event accross Threads in Java?如何在 Java 中跨线程传递事件?
【发布时间】:2017-06-25 22:07:46
【问题描述】:

在 Java 中,如何将事件从子线程传递到主线程,不会在循环中冻结主线程

在线我只能找到涉及主线程陷入无限while循环检查shared thread-safe event FIFO queue(孩子放置事件的位置)中的事件的解决方案。 然后睡x 秒并重新开始。

我需要激活主线程并做其他事情,例如能够处理来自 gui 的事件。当子线程中发生某些事情时,主线程必须调用.eventHappened()

【问题讨论】:

  • 你需要的是一个listener线程,当有事情要做时,它将事件数据传递给主OBJECT。此事件数据将在侦听器线程中处理。否则,您需要主线程进行检查。你用了多少个用户名?
  • 请详细说明您的线程模型。原始线程?执行者? AWT?摇摆? SWT?
  • 主线程是我创建所有 gui (Swing) 的地方。另一个是原始工作线程,下载并解析它。有效,感谢您的回答,但是在侦听器线程上,我遇到了同样的问题,如何将处理后的事件交给主线程?
  • 为了以后的使用和个人理解,我想知道,但在这种特定情况下,我需要主线程上的事件,以便我可以更新 Swing gui 相应地。我在几篇文章中读到,如果您将摇摆组件传递给多个线程和/或尝试从单独的线程更新它们,则会发生不好的事情。
  • 然后有一个 gui 发布工作的队列和一个发布工作结果的第二个队列。要在 UI 中显示结果,您需要另一个线程和一些 ui 的异步调用

标签: java multithreading events


【解决方案1】:

为了避免冻结 UI,这应该可以解决问题:

1) 工作线程或工作线程池正在检查其运行方法的传入工作并发队列。

2) 工作完成并发队列,其中侦听器线程(不同于 UI 线程)在循环中检查。侦听器线程使用异步设施/方法调用 UI 更新以避免 UI 异常。

因此,UI 线程为传入的工作队列提供事件或数据。工作线程拾取它,完成工作并将结果发布到工作完成队列。

侦听器线程检查工作完成队列中的新项目,并将结果异步发布到 UI。

【讨论】:

  • 您能否详细说明一下:在这种方法中,我们需要异步访问 AWT 调度线程,因为规范说所有 gui 代码都需要从该线程运行。所以去那里,我们使用 SwintUtils.InvokeLater。但是,为什么我们可以直接从主线程调用方法呢?毕竟是主程序的线程,而不是 AWT 事件调度线程。我错了吗?
  • AsyncInvoke later 是另一个“工作”队列,但用于 UI 主线程。这对我们来说是透明的。
  • UI 主线程是我第一次创建 gui 元素的线程?
  • 是的。如果您查看 jvm 创建的线程,您会注意到该线程以及其他线程,例如 GC 等
  • 我明白了。所以从我创建第一个 gui 元素的那一刻起,它就不再是主线程,我基本上处于 UI 调度线程中
【解决方案2】:

如果您确实需要以这种方式使用子线程,您可能需要使用并发队列。

如果您使用的是 swing,您可以使用 SwingUtilities.invokeLater() 来执行代码。然后它将在后台线程中运行它,而不是手动使用子线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多