Multithreading 事件调度线程绘制

Multithreading 事件调度线程绘制,multithreading,swing,java-2d,Multithreading,Swing,Java 2d,我正在写一个世嘉主系统模拟器。迄今为止的设计是GUI(JFrame子类等)通过EventQueue.invokeLater()调用在事件调度线程中运行,所有模拟器函数在单独的线程中运行。据我所知,这应该是一个很好的实践,因为EDT应该初始化和更新GUI,而Swing不是线程安全的 这就引出了一个小问题——控制台在单独的线程(Z80、VDP等)中运行,VDP(完成后)将更新BuffereImage。只要我将这个BuffereImage标记为“synchronized”,那么从EDT(特别是GUI的

我正在写一个世嘉主系统模拟器。迄今为止的设计是GUI(JFrame子类等)通过EventQueue.invokeLater()调用在事件调度线程中运行,所有模拟器函数在单独的线程中运行。据我所知,这应该是一个很好的实践,因为EDT应该初始化和更新GUI,而Swing不是线程安全的

这就引出了一个小问题——控制台在单独的线程(Z80、VDP等)中运行,VDP(完成后)将更新BuffereImage。只要我将这个BuffereImage标记为“synchronized”,那么从EDT(特别是GUI的绘制方法)访问它是否安全?我问这个问题,否则我将不得不在paint方法本身中加入大量的VDP逻辑,我宁愿不这样做,因为这会降低GUI的整体速度

我知道一个简单的问题,但我还是习惯于用Java2D制作速度相当快的动画。值得一提的是,在逻辑线程中调用repaint()方法之后,逻辑线程将一直休眠,直到下一帧过程被唤醒,所以我猜这种设计不会对性能造成影响-对吗

非常感谢,, 菲尔·波特


更新我应该使用更好的语言-VDP将通过同步setter方法访问BuffereImage,EDT将通过同步getter方法访问它。

我认为您不需要使setter和getter同步,因为它们应该只从EDT访问。让我们后退一步。您说过getter将从EDT访问——所以我们在这里是线程安全的。现在,setter方法将在VDP上运行——为了处理这种情况,我们希望调用invokeLater(参见示例)。查看更多信息

Runnable updateAComponent = new Runnable() {

    public void run() { 
//this will run in the EDT
component.doSomething(); 

}

};
//this will run in the VDP
SwingUtilities.invokeLater(updateAComponent);

您应该向我们展示一些显示您计划执行的操作的代码,因为“将BuffereImage标记为已同步”没有多大意义。方法或代码块可以同步,但不能同步类型。对不起,我应该使用更正确的语言-我的意思是,当VDP更新BuffereImage时,它将通过同步的“setter”方法进行同步,当JFrame绘制它时,它将通过同步的“getter”方法进行同步。由于在EDT中绘制时逻辑线程将处于休眠状态,因此EDT不应等待对象锁定,因此我认为这应该可以工作。我不确定的原因是网上有很多东西说GUI永远不会从另一个线程更新(虽然在这种情况下是EDT进行绘制,所以我认为我没问题)。为什么不简单地使用SwingUtilities.invokeLater()将图像从背景线程传递到EDT?我认为该方法只允许在EDT上安排可运行任务?我希望在EDT中绘制BuffereImage,而不是在EDT上运行可运行对象。如果我误解了您所说的话,请道歉。如果Runnable的run方法包含在绘制图像中,请将Runnable传递给SwingUtilities.invokeLater使EDT绘制图像。这不是你想要做的吗?所以这个解决方案意味着当逻辑线程来更新BuffereImage时,它只是将更新工作分配给EDT?我不这么想,但我想那会管用的。这实际上意味着只能从EDT访问BuffereImage(即使它是由逻辑线程实例化的)。