我有三个问题密切相关,因为它们彼此诞生并代表了一系列思路,所以我将它们发布在一个问题之下。如果我单独发布它,那对我构建我的问题的大图片无济于事。
1)你能用简单的语言解释SwingUtilities.invokeLater
的作用吗?我理解线程,我敢说了很多,但文档的语言仍然让我感到困惑。它说:
导致 doRun.run()异步执行 AWT事件调度线程。毕竟这会发生 待处理的AWT事件已经处理完毕。这个方法应该 在应用程序线程需要更新GUI时使用。 在以下示例中,
invokeLater
呼叫队列Runnable
对象doHelloWorld
在事件调度线程和 然后打印一条消息。
如果我付出一些努力来理解所说的内容,我认为这就是它所说的,但我不能确定它。我想它说:
invokeLater
方法仅在应用程序的主线程上调度主窗口创建和调度程序/消息泵的设置,而不是在单独的线程上。它通过发布消息来创建窗口并在主/主应用程序线程上进行设置。换句话说,主要话题是对我们说,"你要我创建的窗口将在我完成其他现在的工作之后创建。"
但是有两件事让我感到困惑,我将其列为下面的两个问题。
2)那么为什么我需要将新窗口的消息循环实现为Runnable
。这意味着我想要一个单独的线程来执行该消息循环。
3)我在创建窗口的函数和窗口的消息循环函数中打印出当前线程ID,它们都是不同的线程。那么,Swing中的每个窗口都在自己的线程上运行?那太疯狂了。你能告诉我这里发生了什么吗?如果你能在一段或两段中解释在Swing中创建的GUI应用程序的线程模型?
public static void main(String[] args) {
SwingUtilities.invokeLater(new MainWindowEventLoop());
System.out.println(String.format("Main thread %1$d started.",
Thread.currentThread().getId()));
}
public class MainWindowEventLoop implements Runnable {
@Override
public void run() {
JFrame mainWindow = new MainWindow("Main Window");
System.out.println(String.format("Main window loop running on thread %1$d.",
Thread.currentThread().getId()));
}
}
输出:
主线程1已启动。
主要窗口循环在线程14上运行。
答案 0 :(得分:6)
这有点复杂,但Swing不是线程安全的。为了以异步和安全的方式运行GUI,Sun / Oracle使用称为Ad-Hoc Thread Confinement的锁定模式。所有Swing组件必须在AWT EDT(事件调度线程)上运行,否则结果不是线程安全的。
这是Oracle教程的链接。尝试阅读所有这些部分,看看它是否更有意义。
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/
每个窗口都不会在自己的单独线程上运行。只有一个EDT。每个窗口都在SAME线程EDT上运行。当EDT有机会时,您发送给EDT的每个Runnable
将依次执行,一个接一个地执行。因此invokeLater()
的“后期”部分。
答案 1 :(得分:0)
基本上所有的挥杆窗都与主线有关。 swing中的每个组件都以线程形式运行。完成事件控制后,再次返回主线程,等待事件发生。