208.SwingWorker

Swing程序UI界面只能使用EDT线程来修改和更新,不能使用其他线程。

原文:

http://www.oracle.com/technetwork/articles/javase/swingworker-137249.html#Right

翻译:

http://blog.sina.com.cn/s/blog_4b6047bc010007so.html

208.SwingWorker_第1张图片

Image Search示例的主类是MainFrame,从其main方法启动。许多程序使用下面方法启动界面,但这是错误的启动UI界面的方法

public class MainFrame extends javax.swing.JFrame {

  public static void main(String[] args) {

new MainFrame().setVisible(true);
  }

}
        
尽管这种错误出现在开始,但仍然违反了不应在EDT外的其他线程同Swing组件交互的原则。这个错误尤其容易犯,线程同步问题虽然不是马上显示出来,但是还要注意避免这样书写。
        正确启动UI界面应该如下

public class MainFrame extends javax.swing.JFrame {
  ...

  public static void main(String[] args) {
   
 SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new MainFrame().setVisible(true);
      }
    });
  }
}

 

在初始化线程中使用invokeLater方法能正确的初始化程序界面。就像前面文章所提到的,此方法是异步执行的,也就是说调用会立即返回。创建界面后,大部分初始化线程基本上就结束了。
        通常有两种办法调用此方法:
    * SwingUtilities.invokeLater
    * EventQueue.invokeLater
        两个方法都是正确的,选择任何一个都可以。实际上,SwingUtilities版只是一个薄薄的封装方法,它直接转而调用EventQueue.invokeLater。因为Swing框架本身经常调用SwingUtilities,使用SwingUtilities可以减少程序引入的类。
        另种将任务放到EDT执行的方法是SwingUtilities.invokeAndWait,不像invokeLaterinvokeAndWait方法是阻塞执行的,它在EDT上执行Runnnable任务,直到任务执行完了,该方法才返回调用线程。
        invokeLaterinvokeAndWait都在事件派发队列中的所有事件都处理完之后才执行它们的Runnable任务,也就是说,这两个方法将Runnable任务放在事件队列的末尾。
        注意:虽然可以在其他线程上调用invokeLater,也可以在EDT上调用invokeLater,但是千万不要在EDT线程上调用invokeAndWait方法!很容易理解,这样做会造成线程竞争,程序就会陷入死锁。

 

如果想结束一个线程,不要使用stop方法,而是将线程的对象赋值为null。

 

你可能感兴趣的:(208.SwingWorker)