Java 中的主线程与 UI 线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7156949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Main Thread vs. UI Thread in Java
提问by MByD
In many Swing snippets given here as answers, there is a call to SwingUtilities#invokeLater
from the main
method:
在此处作为答案给出的许多 Swing 片段中,有一个SwingUtilities#invokeLater
从main
方法调用:
public class MyOneClassUiApp {
private constructUi() {
// Some Ui related Code
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MyOneClassUiApp().constructUi();
}
});
}
}
But according to the Threads and Swing article, it is safe to construct UI from main thread:
但是根据Threads and Swing 文章,从主线程构造 UI 是安全的:
A few methods are thread-safe: In the Swing API documentation, thread-safe methods are marked with this text:
This method is thread safe, although most Swing methods are not.
An application's GUI can often be constructed and shown in the main thread: The following typical code is safe, as long as no components (Swing or otherwise) have been realized:
一些方法是线程安全的:在 Swing API 文档中,线程安全的方法标有以下文字:
这种方法是线程安全的,尽管大多数 Swing 方法不是。
应用程序的 GUI 通常可以在主线程中构建和显示: 只要没有实现任何组件(Swing 或其他),以下典型代码是安全的:
public class MyApplication {
public static void main(String[] args) {
JFrame f = new JFrame("Labels");
// Add components to
// the frame here...
f.pack();
f.show();
// Don't do any more GUI work here...
}
}
So, is there a real (thread safety) reason to construct the UI in main through SwingUtilities#invokeLater
, or this is just a habit, to remember do it in other cases?
那么,在 main through 中构造 UI 是否有真正的(线程安全)理由SwingUtilities#invokeLater
,或者这只是一种习惯,记住在其他情况下这样做?
回答by trashgod
"The Swing single-thread rule: Swing components and models should be created, modified, and queried onlyfrom the event-dispatching thread."—Java Concurrency in Practice, also discussed hereand here. If you don'tfollow this rule, then you can't reliably construct, modify or query any component or model that may have assumed that you didfollow the rule. A program may appearto work correctly, only to fail mysteriously in a different environment. As violations may be obscure, verify correct usage by using one of the approaches mentioned here.
“ Swing 单线程规则:Swing 组件和模型只能从事件调度线程创建、修改和查询。”— Java 并发实践,也在此处和此处讨论。如果您不遵循此规则,那么您将无法可靠地构建、修改或查询任何可能假定您确实遵循该规则的组件或模型。一个程序可能看起来工作正常,但在不同的环境中却神秘地失败了。由于违规可能不明确,请使用此处提到的方法之一验证正确使用。
回答by Paul
It's safe to create your Swing UI in the main method because how would other components be displayed before you set up your UI? As long as you haven't thrown some stuff on the screen already you'll be fine. In other words, this would be bad:
在 main 方法中创建 Swing UI 是安全的,因为在设置 UI 之前其他组件将如何显示?只要你还没有把一些东西扔到屏幕上,你就没事了。换句话说,这会很糟糕:
public class MyApplication
{
public static void main(String[] args)
{
JFrame f = new JFrame("Labels");
// Add components to
// the frame here...
f.pack();
f.show();
// now make another frame:
JFrame f2 = new JFrame("Labels2");
// Add components to the 2nd frame here...
f2.pack();
f2.show();
}
}
If you did the above you'd have JFrame f
up and running then you'd be adding Swing UI components off the Event Dispatch Thread (EDT). invokeLater
runs the code on the EDT - it won't hurt to use it if you want extra peace of mind.
如果您执行了上述操作,那么您就已经JFrame f
启动并运行了,那么您将在 Event Dispatch Thread (EDT) 之外添加 Swing UI 组件。 invokeLater
在 EDT 上运行代码 - 如果您想要更加安心,使用它不会有什么坏处。
回答by AlexR
I think that using SwingUtiltities.invokeLater()
is just an easier way to execute some code asynchronously. Sometimes it is required for certain application: for example you can create 2 separate windows simultaneously. Nothing more.
我认为 usingSwingUtiltities.invokeLater()
只是异步执行某些代码的一种更简单的方法。有时某些应用程序需要它:例如,您可以同时创建 2 个单独的窗口。而已。