为什么EventDispatchThread排在首位?

时间:2009-02-21 12:45:51

标签: java swing edt

这是我不明白的设计决定。

Android和JME都遵循以下策略:启动应用程序的线程是UI线程,您需要注意将耗费资源的东西卸载到另一个线程。

另一方面,在Swing中,您使用EventQueue.invokeLater(Runnable)进行用户界面,使用SwingWorker进行后台处理。

现在,主线程是什么?

2 个答案:

答案 0 :(得分:4)

如此Sun article about thread中所述,您可以在主线程中执行任何操作,包括构建GUI,即使它存在风险。

  • Swing方法不是线程安全的,但只要没有实现组件(Swing或其他)(意味着组件的paint()方法已经或可能被调用),直到2004年才可以。
  • 自2004年以来,SO question提醒,mandatory to create the GUI in the EDT

回到问题:

Swing尚未实现与主要线程仅与GUI相关,因为这将强制采用纯多线程方法并且:

  • 组件开发人员无需深入了解线程编程:所有组件必须完全支持多线程访问的工具包很难扩展,特别是对于开发人员而言不是线程编程方面的专家。

  • 以可预测的顺序调度事件invokeLater()排队的可运行对象将从与鼠标和键盘事件,计时器事件和绘制请求相同的事件队列中调度。
    在组件支持多线程访问的工具包中,组件更改与线程调度程序随心所欲的事件处理交错。这使得全面测试变得困难或不可能。

  • 减少开销:尝试小心锁定关键部分的工具包可能会花费大量时间和空间来管理锁定。
    每当工具包调用可能在客户端代码中实现的方法(例如,公共类中的任何公共或受保护方法)时,工具包必须保存其状态并释放所有锁,以便客户端代码可以在必要时获取锁。登记/> 当控制从方法返回时,工具包必须重新锁定其锁并恢复其状态。尽管大多数应用程序不需要并发访问GUI,但所有应用程序都承担了这一成本。

因此主线程可用于 初始化 (数据和GUI,只要它们不花费太多时间),而大多数 后期初始化GUI步骤 自然发生在事件派发线程中 一旦GUI可见,大多数程序都由按钮动作或鼠标点击等事件驱动,这些事件总是在事件派发线程中处理。

答案 1 :(得分:1)

java启动器不是Swing(或AWT)特有的。 main是一个通用的切入点。 AWT将在调用main后按需启动事件调度线程,因此无法使用主线程。它甚至可以退出EDT并开始一个新的。

更奇怪的是,在AWT EDT上没有调用applet生命周期方法。

主线程只是为执行main方法而创建的线程。