【问题标题】:Is there a way to set up two or more the event dispatch thread (EDT)?有没有办法设置两个或多个事件调度线程(EDT)?
【发布时间】:2015-03-05 13:18:54
【问题描述】:

Java 是否能够一次创建多个 EDT?

我正在尝试设置 EDT,以及它如何更新“重型”面板的内容,其中可能嵌入了十几个面板,总共包含数百个组件。目前我有

        public void run() {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    panel.update();
                }
            });
        }

我看过以下帖子:

Measuring "busyness" of the event dispatching thread

How does the event dispatch thread work?

Java Event-Dispatching Thread explanation

http://en.wiki2.org/wiki/Event_dispatching_thread

等等。

我有点理解,如果有十几个事件需要单个 EDT 处理,Java 已经有一个内部调度机制来对这些事件进行分组/优先级排序。

根据http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

"This is necessary because most Swing object methods are not "thread safe": invoking them from multiple threads risks thread interference or memory consistency errors."

如果我在下面创建一个带有 new Thread(new Runnable() { ... }.start() 的第二个 EDT 会怎样?

java会因为担心线程安全而自动将两个EDT合并回一个吗?

       new Thread(new Runnable() {
        public void run() {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    panel.update();
                }
            });
        }
    }).start();

【问题讨论】:

  • 你的第二个线程不是 EDT,只是 T。;)
  • 我认为您无法创建 EDT。 Swing 创建了自己的 EDT。您可以创建任意数量的线程(最高限制),但它们不会是 EDT。您的示例代码创建了一个Runnable 对象,但它不会在您的线程中运行panel.update。相反,这个对象被交给了 Swing,它把它保存在某个地方,然后最终 EDT 找到它并运行它。

标签: java multithreading event-dispatch-thread


【解决方案1】:

只能有一个事件调度线程!

但是为什么你甚至想要有多个线程呢?即使对于具有许多组件的“重型”面板(在我目前正在处理的应用程序中,必须有 1000 个组件),一个 EDT 就足够了。请记住,您不应在 EDT 上执行任何占用大量 CPU 时间的任务。否则,您将阻止 EDT 更新事件,并且您的 GUI 将在响应用户输入时变得“迟缓”。

还请记住,所有 GUI 组件都应仅在 EDT 内创建和操作,因为许多组件不是线程保存的。忽略此指南可能适用于特定任务,但迟早您会遇到奇怪的行为和/或崩溃!

【讨论】:

  • 我在一个类中完成了一些计算,该类也负责创建面板和组件。所以我认为将核心逻辑从 GUI 分离到不同的类对我来说是一个好习惯
  • 正确!一般来说,您想看看Model-View-Controller 模式。还要记住始终确保在 EDT 上执行 GUI 组件的创建和操作。大多数情况下,当您从内部调用代码时,这种情况会自动发生,例如ActionListener(在 EDT 上运行),但有时您想从不同的线程访问 GUI 元素,然后您将不得不使用 SwingUtilities.invokeLater 或 SwingUtilities.invokeAndWait。
【解决方案2】:

Swing GUI 是单线程的。那个单线程就是 EDT。如果您想引入第二个 EDT(并且仍然让 GUI 正常工作),您还必须重写大量内部 Swing 代码以解决线程安全增加的复杂性。

添加另一个 EDT 会带来更多的复杂性,从而导致未知数量的性能增加(或减少)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 2011-11-11
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    相关资源
    最近更新 更多