# 初始线程

> 原文： [https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)

每个程序都有一组应用程序逻辑开始的线程。在标准程序中，只有一个这样的线程：调用程序类的`main`方法的线程。在 applet 中，初始线程是构造 applet 对象并调用其`init`和`start`方法的线程;这些操作可能发生在单个线程上，也可能发生在两个或三个不同的线程上，具体取决于 Java 平台实现。在本课中，我们将这些线程称为 _ 初始线程 _。

在 Swing 程序中，初始线程没有太多事情要做。他们最重要的工作是创建一个`Runnable`对象，初始化 GUI 并安排该对象在事件派发线程上执行。创建 GUI 后，程序主要由 GUI 事件驱动，每个事件都会导致在事件调度线程上执行短任务。应用程序代码可以在事件调度线程上调度附加任务（如果它们快速完成，以免干扰事件处理）或工作线程（对于长时间运行的任务）。

初始线程通过调用 [`javax.swing.SwingUtilities.invokeLater`](https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#invokeLater-java.lang.Runnable-) 或 [`javax.swing.SwingUtilities.invokeAndWait`](https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#invokeAndWait-java.lang.Runnable-) 来调度 GUI 创建任务。这两种方法都只采用一个参数：`Runnable`定义新任务。他们唯一的区别在于他们的名字：`invokeLater`只是安排任务并返回; `invokeAndWait`在返回之前等待任务完成。

您可以在整个 Swing 教程中看到这方面的示例：

```
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        createAndShowGUI();
    }
});

```

在 applet 中，必须使用`invokeAndWait`从`init`方法启动 GUI 创建任务;否则，`init`可能会在创建 GUI 之前返回，这可能会导致 Web 浏览器启动 applet 时出现问题。在任何其他类型的程序中，调度 GUI 创建任务通常是初始线程所做的最后一件事，因此它是否使用`invokeLater`或`invokeAndWait`并不重要。

为什么初始线程不是简单地创建 GUI 本身？因为几乎所有创建 Swing 组件或与 Swing 组件交互的代码都必须在事件派发线程上运行。此限制将在下一节中进一步讨论。