在为游戏制作动画和更新计时器时,我了解到任何与 GUI 相关的 Activity 都应该在 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。我试过这个,它确实有效。但是,像这样嵌套线程似乎不是一个好主意。
那么,像这样嵌套线程并没有看起来那么糟糕吗?如果这是一个坏主意,那么确保
ScheduledExecutorService
在 EDT 上运行的正确方法是什么? 最佳答案
在您的代码中:
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.
}
}
这是我最好的建议,没有看到您的其余代码在做什么。
关于java - 如何保证 ScheduledExecutorService 在 EDT 上运行?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23596620/