在处理动画和更新游戏计时器时,我读到任何与GUI相关的活动都应该在EDT上运行,包括重新绘制屏幕。我使用单个ScheduledExecutorService
来更新和绘制游戏(使用活动渲染)。服务的初始计划(这是一个implements Runnable
的嵌套类)在这样的调用中完成:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ex.schedule(new UpdatingService(), 1, TimeUnit.MILLISECONDS);
}
});
我认为这会使服务在EDT上运行,但添加System.out.println(SwingUtilities.isEventDispatchThread());
证明它不是。
我做了一些搜索,发现this帖子提到了启动EDT 里面的计时器。我尝试了这个,它确实有效。但是,像这样嵌套线程似乎不是一个好主意。
那么,像这样嵌套线程并不像看起来那么糟糕吗?如果这是一个坏主意,那么确保{1}在EDT上运行的正确方法是什么?
答案 0 :(得分:4)
在您的代码中:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ex.schedule(new UpdatingService(), 1, TimeUnit.MILLISECONDS);
}
});
此处在EDT上执行的唯一代码是ex.schedule
调用。稍后由调度程序调用的代码,例如new UpdatingService()
将在调度程序内部的线程上运行,该线程不是EDT,而是由Executors.newSingleThreadScheduledExecutor
调用创建的某个线程
也许我要做的就是让你的调度程序安排一个更新方法(也许你的更新服务),然后通过invokeLater将调用放到EDT上。
例如:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.schedule(new Updater(), 1, TimeUnit.MILLISECONDS);
...
class Updater extends Runnable {
@Override
public void run() {
// invoke the EDT via Swing Utilities here.
}
}
这是我最好的建议,而不会看到你的其余代码在做什么。