【发布时间】:2011-12-27 23:08:54
【问题描述】:
只是一个快速的 - 我正在编写 Sega Master System 模拟器。到目前为止的设计是 GUI(JFrame 子类等)通过 EventQueue.invokeLater() 调用在事件调度线程中运行,并且所有仿真器函数在单独的线程中运行。据我了解,这应该是一种很好的做法,因为 EDT 应该初始化和更新 GUI,而 Swing 不是线程安全的。
这引出了一个小问题——控制台在单独的线程(Z80、VDP 等)中运行,而 VDP(当我完成它时)将更新一个 BufferedImage。只要我将此 BufferedImage 标记为“同步”,然后从 EDT 访问它(特别是 GUI 的绘制方法)是否安全?我这样问,否则我将不得不将大量 VDP 逻辑放入绘制方法本身,我宁愿不这样做,因为它会降低整个 GUI 的速度。
我知道一个简单的问题,但我仍然习惯于推动 Java2D 以获得不错的速度动画。值得一提的是,在逻辑线程中调用 repaint() 方法之后,逻辑线程将一直休眠,直到为下一帧传递唤醒,所以我猜这种设计不会对性能造成影响 - 我对吗?
非常感谢, 菲尔·波特
更新我应该使用更好的语言 - VDP 将通过同步的 setter 方法访问 BufferedImage,而 EDT 将通过同步的 getter 方法访问它。
【问题讨论】:
-
您应该向我们展示一些代码,说明您打算做什么,因为“将 BufferedImage 标记为同步”没有多大意义。方法或代码块可以同步,但类型不能同步。
-
抱歉,我应该使用更正确的语言 - 我的意思是当 VDP 更新 BufferedImage 时,它将通过同步的“setter”方法进行更新,并且当 JFrame 绘制它时 - 它会这样做所以通过同步的“getter”方法。由于在 EDT 中进行绘画时逻辑线程将处于休眠状态,因此 EDT 不应该等待对象上的锁定,因此我认为这应该可以工作。我不确定的原因是网上有很多东西说 GUI 永远不会从另一个线程更新(尽管在这种情况下是 EDT 进行绘画,所以我认为我没问题)。
-
为什么不简单地使用 SwingUtilities.invokeLater() 将图像从后台线程传递到 EDT?
-
我认为该方法只允许在 EDT 上安排可运行任务?我想在 EDT 中绘制 BufferedImage,而不是在 EDT 上运行 Runnable 对象。抱歉,如果我误解了您所说的内容。
-
如果 Runnable 的 run 方法包括绘制图像,则将 runnable 传递给 SwingUtilities.invokeLater 使 EDT 绘制图像。这不是你想做的吗?
标签: multithreading swing java-2d