为什么需要将 GUI 更新代码放入 SwingUtilities.invokeLater()
中呢?
为什么不能由 Swing 自己内部处理?为什么调用者必须关心 Swing 如何处理 UI 更新?
Swing对象不是线程安全的。 SwingUtilities.invokeLater()
允许某个任务在稍后的某个时间执行,正如其名称所示;但更重要的是,任务将在AWT事件派发线程上执行。使用 invokeLater
时,任务是异步执行的;还有一个 invokeAndWait
,它不会在任务完成执行之前返回。
关于不使Swing线程安全的一些信息可以在此处找到:多线程工具包:一个失败的梦? [已存档]
invokeLater
更新将把它从您的线程中移除并放入事件线程中。invokeLater
发出通知。这样可以保持 GUI 响应事件和重绘。如果更新非常广泛,您甚至可以在更新过程中每一秒钟或两秒钟使用 invokeLater
定期发出这些通知。调用此方法将会异步地在AWT事件派发线程上执行doRun.run()方法。这将会在所有待处理的AWT事件被处理完后执行。当应用程序线程需要更新GUI时,应该使用此方法。
...
重复他人的话:Swing不是线程安全的,因此一个线程必须执行所有更新以避免并发问题。invokeLater是一个实用方法,用于在事件处理线程中执行某些操作。
为什么Swing不在内部执行:这是我的印象...我认为这会过度 - 检查每个更新发生的地方。它会使Swing代码膨胀,难以审查和维护代码。
另一方面,对于应用程序来说,知道它是否在GUI线程中执行并调用invokeLater并不那么困难。当应用程序在启动某个线程之前时,就会出现这种情况。