问题标签 [event-dispatch-thread]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
1934 浏览

java - 将变量传递给事件调度线程

我的 GUI 被锁定,因为我需要通过 EDT 更新它,但是,我还需要传递一个正在使用 GUI 更新的变量:

这不起作用。我需要在 EDT 中设置文本,但我不能将 numOfPlayers 传递给它而不将其声明为最终的(我不想这样做,因为它随着新玩家加入服务器而改变)

0 投票
6 回答
1415 浏览

java - EDT 和主线程之间的通信

我一直在问很多关于我最近一直在做的项目的问题。这是我所处的场景,任何帮助或指向正确方向都会有很大帮助......

这是一个由服务器和多个客户端构建的网络程序。每个客户端都有一个 GUI,它必须根据服务器发送的命令进行操作。每个客户端都包装在一个名为Player. 这Player有一个 GUI(扩展JFrame)和一个 main 方法,而服务器只有一个 main 方法(没有 GUI)。起初,这个类是在主线程中创建的,如下所示:

这工作得很好,直到我意识到整个Player类现在都在 EDT 中执行。因此,当我等待来自服务器的命令时,整个 GUI 会锁定,直到发送该命令并执行适当的操作。可以想象,这是一个可怕的设计,并且被证明是编码环境的真正痛苦,因为每次您想要检查某些东西时,您必须找到一些疯狂的工作,以便 GUI 仍然保持完整。

显然,我必须在单独的线程中检查来自服务器的命令并在 EDT 中运行 GUI 组件。我的第二个实现有两个类——一个用于 GUI,一个用于Player. 这个想法是Player有一个保存 GUI 的变量,以便我可以从Player类中访问 GUI,如下所示:

这也不起作用,因为thisRunnable对象内部指的是Runnable对象,而不是Player.

如何Player在一个线程中的类与 EDT 线程中相应的 GUI 类之间进行通信?

0 投票
5 回答
14488 浏览

java - 防止 Swing GUI 在后台任务期间锁定

我有一个存储对象列表的摇摆应用程序。当用户点击一个按钮时,

我想对列表中的每个对象执行两个操作,然后在完成后在 JPanel 中绘制结果。我一直在尝试 SwingWorker、Callable 和 Runnable 来进行处理,但无论我做什么,在处理列表时(可能需要几分钟,因为它是 IO 绑定的),GUI 被锁定。

我有一种感觉,这可能是我调用线程或其他东西的方式,还是与绘图功能有关?这不是线程,因为它非常快。

我也必须按顺序执行两个处理阶段,那么确保第二个处理阶段等待第一个处理阶段的最佳方法是什么?我使用了 join(),然后

尝试确保这一点,但我担心这也可能是我的问题的原因。

我一直在到处寻找一些指示,但是由于我找不到任何指示,所以我确定我在这里做了一些愚蠢的事情。

0 投票
8 回答
896 浏览

java - 面对 EDT,如何管理游戏状态?

我正在 Java 平台上开发一个实时战略游戏克隆,我有一些关于放置位置和如何管理游戏状态的概念性问题。游戏使用 Swing/Java2D 作为渲染。在当前的开发阶段,没有模拟和人工智能,只有用户能够改变游戏的状态(例如,建造/拆除建筑物、添加-移除生产线、组装车队和设备)。因此,可以在事件调度线程中执行游戏状态操作,而无需任何渲染查找。游戏状态还用于向用户显示各种聚合信息。

但是,由于我需要引入模拟(例如,建筑进度、人口变化、舰队移动、制造过程等),在 Timer 和 EDT 中更改游戏状态肯定会减慢渲染速度。

假设每 500 毫秒执行一次模拟/AI 操作,我使用 SwingWorker 进行大约 250 毫秒长度的计算。我如何确保模拟和可能的用户交互之间的游戏状态读取不存在竞争条件?

我知道模拟结果(即少量数据)可以通过 SwingUtilities.invokeLater() 调用有效地移回 EDT。

游戏状态模型似乎太复杂以至于无法在任何地方都使用不可变值类。

是否有相对正确的方法来消除这种读取竞争条件?也许在每个计时器滴答声上进行完整/部分游戏状态克隆,或者将游戏状态的生存空间从 EDT 更改为其他线程?

更新:(根据我给出的评论)该游戏由 13 名 AI 控制的玩家、1 名人类玩家组成,并且有大约 10000 个游戏对象(行星、建筑物、设备、研究等)。例如,游戏对象具有以下属性:

在一个场景中,用户在这个星球上建造了一座新建筑。这是在 EDT 中执行的,因为需要更改地图和建筑物集合。与此同时,每 500 毫秒运行一次模拟,以计算所有游戏星球上建筑物的能量分配,这需要遍历建筑物集合以进行统计收集。如果计算了分配,则将其提交给 EDT,并分配每个建筑物的能量场。

只有人类玩家交互具有此属性,因为 AI 计算的结果无论如何都会应用于 EDT 中的结构。

通常,75% 的对象属性是静态的,仅用于渲染。其余部分可以通过用户交互或模拟/人工智能决策进行更改。还确保在前一个步骤写回所有更改之前不会启动新的模拟/AI步骤。

我的目标是:

  • 避免延迟用户交互,例如用户将建筑物放置在地球上,并且仅在 0.5s 后才获得视觉反馈
  • 避免用计算、锁等待等阻塞 EDT。
  • 避免集合遍历和修改、属性更改的并发问题

选项:

  • 细粒度对象锁定
  • 不可变集合
  • 挥发性领域
  • 部分快照

所有这些对模型和游戏都有优点、缺点和原因。

更新2:我说的是这个游戏。我的克隆在这里。屏幕截图可能有助于想象渲染和数据模型的交互。

更新 3:

我将尝试提供一个小代码示例来澄清我的问题,因为从评论中似乎它被误解了:

所以重叠是在onAddBuildingClicked() 和distributePower() 之间。现在想象一下,在游戏模型的各个部分之间有 50 个这样的重叠。

0 投票
3 回答
1610 浏览

java - 从 EDT 外部获取 Swing 组件的值

我当前的代码如下所示:

最终数组的使用似乎有点小技巧。有没有更优雅的解决方案?

我已经做了很多搜索,但我似乎无法找到任何可以做到这一点的东西,这让我感到惊讶。虽然我不断遇到SwingWorker,但我不确定这是否适合这种情况?

我假设这JTextArea.getText()不是线程安全的。

谢谢。

0 投票
2 回答
2044 浏览

java - 是否可以在不使用 EDT 的情况下在 Java Swing 中执行主动渲染?

我正在研究使用缓冲区策略和 Javadoc 中描述的以下技术:

}

避免EDTinvokeLater/或invokeAndWait在执行动画时会很棒。

我的问题:

  • 如果这是在 Swing 应用程序中,我们不需要担心将调用show放在 EDT 上吗?
  • 其他人可以在 Swing 应用程序中看到任何问题吗?

这是受到游戏编程这个有趣答案的启发。

0 投票
3 回答
231 浏览

java - Java:是否有 SwingUtilities.invokeNowOrLaterIfEDT(...) 或类似的?

(请务必阅读下面的编辑,这个问题显然令人困惑,我很抱歉)

这是一个典型的SwingUtilities.invokeLater调用:

现在我想要一个SwingUtilities.invokeNowOrLaterIfEDT.

当然,我可以使用自己的实用程序类,如下所示:

但这有一个缺点,即每次从 EDT 调用它时都会创建一个新线程(并且必须等待该新线程被调度)。

另一种方法是使用一个在应用程序生命周期期间运行的额外线程(可以延迟实例化),使用一些阻塞队列将Runnables. 这样做的好处是,每次我从 EDT 调用这样的方法时,都不会经常创建线程。

默认 Java API 中是否存在类似的内容?

什么会更好:每次从 EDT 调用它时只需创建一个新线程,就像上面的示例一样,或者有一个额外的线程在RunnablesEDT 之外执行,或者其他什么?

编辑:就像SwingUtilities.invokeLater可能会或可能不会从 EDT 调用一样,我想到的方法可能会或可能不会从 EDT 调用。它是执行完全异步的操作,可能会或可能不会从 GUI / EDT 上的用户操作触发。我认为SwingUtilities.invokeLater能够在 EDT 中运行某些东西非常方便,而无需关心是否在 EDT 上调用它。而且我认为invokeNowOrLaterIfEDT(...)我上面展示的非常方便。但我可能错了。对这种方法的需要是疯狂的吗?现在我开始怀疑了!?

编辑二:我一点都不清楚,我意识到这一点,对此感到抱歉。我想从 EDT 异步运行的东西不是超长的过程,也不需要像进度条这样的更新或任何显示正在发生的事情的东西。如果它是单线程/排队的也不是问题(显然,我在问题中说明了它)。我根本不是在使用线程池来有效地将负载分散到各种内核等上。只是这些是不需要在 EDT 上运行的小型计算,并且可以从 EDT 调用或不调用。这实际上只是我想在 EDT 之外执行的微小的异步内容。如果它们都在同一个线程上排队等,这不是问题。

但是现在,多亏了你的回答,我也意识到,如果这样的事情是使用单线程和 Runnable 队列实现的,那么通过调用这样一个用于长时间计算的实用方法将很容易自取其辱然后全部排队而不是正确地多线程。

0 投票
4 回答
2356 浏览

java - 使用 invokeAndWait 从 Swing 返回值

我一直在使用以下方法来创建组件并从 Swing 向/从 EDT 外部返回值。例如,以下方法可以是 , 的扩展JFrame,以创建 aJPanel并将其添加到 parent JFrame

本地 1 长度数组用于从RunnableEDT 中调用的内部传输“结果”。好吧,它看起来“有点” hacky,所以我的问题是:

  1. 这有意义吗?还有其他人在做这样的事情吗?
  2. 1-length 数组是传输结果的好方法吗?
  3. 有没有更简单的方法来做到这一点?
0 投票
2 回答
3320 浏览

java - 使线程在来自 EDT 的非 EDT(事件调度线程)线程上运行

我有一个在 EDT 上运行的方法,在其中我想让它在一个新的(非 EDT)线程上执行一些东西。我当前的代码如下:

0 投票
4 回答
3749 浏览

java - 处理事件调度线程

我对“事件调度线程”有疑问。我有一个主类,它也是一个 JFrame。它初始化代码中的其余组件,其中一些不涉及 Swing,而其中一些涉及。像这样使用 EDT 简单地初始化 Main 类就足够了吗?...

这样,一切都将在 Event Dispatcher 线程上运行。