🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
线程与Swing组合时必须遵循的两个原则。 **1. 如果一个动作需要花费很长的时间,则把这个动作放在一个独立的工作器线程中做,而不能放在事件分配线程中做(EventQueue类就是事件分配线程)。** 因为如果花很多的时间在事件分配线程上,应用程序像死了一样,不会响应任何事件。特别是,事件分配线程应该永远不要进行input/output调用,否则可能造成阻塞,而且永远不能调用sleep,如果需要等待指定的时间,应该使用定时器事件。 <br/> **2. 除了事件分配线程,不要在任何线程中接触Swing组件。这叫单一线程规则。** 例如更新label.setText,应该在EventQueue类的`invokeLater`方法,或`invokeAndWait`方法中更新。 <br/> Swing组件应该如下与线程进行组合使用,将更新Swing组件的代码放到实现Runnable接口的`run`方法中。 ``` public void run() { ... EventQueue.invokeLater(() -> { label.setText("..."); }); ... } ``` * `invokeLater`方法:当事件放入事件队列时,`invokeLater`方法立即返回,而`run`方法被异步执行。 * `invokeAndWait`方法:当事件放入事件队列时,`invokeAndWait`方法一直在等待,直到`run`方法确认被执行过为止。 在更新Swing组件时,调用`invokeLater`方法更合适,这样可以让工作器线程更快完成工作,但精度性比`invokeAndWait`稍差。这两个方法都不会创建新的线程。 * java.awt.EventQueue 1.1 * `static void invokeLater(Runnable runnable) 1.2` 等待处理的线程被处理之后,让runnable对象的`run`方法在事件分配线程中执行。 * `static void invokeAndWait(Runnable runnable) 1.2` 等待处理的线程被处理之后,让runnable对象的`run`方法在事件分配线程中被执行。该调用会阻塞,直到`run`方法终止。 * `static boolean isDispatchThread() 1.2` 如果执行该方法的线程是事件分配线程,则返回true。