Wat*_* v2 3 java swing jvm event-dispatch-thread
我有三个问题密切相关,因为它们是彼此诞生的,代表了一个思路,所以我在一个问题下发布它们.如果我单独发布它,我无法帮助我构建我的问题的大局.
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()));
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
主线程1开始了.
主窗口循环在线程14上运行.
这有点复杂,但Swing不是线程安全的.为了以异步和安全的方式运行GUI,Sun/Oracle使用称为Ad-Hoc Thread Confinement的锁定模式.所有Swing组件必须在AWT EDT(事件调度线程)上运行,否则结果不是线程安全的.
这是Oracle教程的链接.尝试阅读所有这些部分,看看它是否更有意义.
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/
每个窗口都不会在自己独立的线程上运行.只有一个EDT.每个窗口都在SAME线程EDT上运行.Runnable发送给EDT的每一个都是顺序执行的,一个接一个地执行,当EDT有机会这样做时.因此,"后来"部分invokeLater().
| 归档时间: |
|
| 查看次数: |
2145 次 |
| 最近记录: |