一 线程类别及为什么要使用SwingWorker
1.1 一个Swing开发人员将会和以下几种线程打交道
- 初始线程:在标准的程序中,只有一个这样的线程:这个线程将调用程序主类中的main方法。在Swing程序中,初始线程主要作用是创建GUI,通过EventQueue的invokeLater方法或者invokeAndWait方法
EventQueue.invokeLater(new Runnable()) {
public void run() {
createAndShowGUI();
}
}
- 事件分派线程(Event dipatch thread EDT):根据单一线程规则,所有的接触Swing组件的代码必须在该线程执行。在该线程执行的事件必须是要能快速完成的,否则事件堆积起来将造成界面响应过慢。
- 工作线程:通常执行所有消耗时间的任务。
1.2 事件分派线程与工作线程:
这些约束意味着需要耗时操作的 GUI 应用程序至少需要以下两个线程:1) 执行长时间任务的工作线程; 2) 所有 GUI 相关活动的事件指派线程 (EDT)这涉及到难以实现的线程间通信。SwingWorker 设计用于需要在后台线程中运行长时间运行任务的情况,并可在完成后或者在处理过程中向 UI 提供更新。SwingWorker 的子类必须实现 doInBackground() 方法,以执行后台计算。(当然也可以采用启动新线程完成耗时任务,但此时应该在线程中使用EventQueue.invokeLater方法来更新用户界面,步骤较为繁琐)
二 使用SwingWorker
2.1 后台任务的典型UI活动
- 工作过程中更新UI显示进度
- 工作完成后做最后的更新
2.2 工作流
工作流
SwingWorker 的生命周期中包含三个线程:
当前线程:在此线程上调用 execute() 方法。它调度 SwingWorker 以在 worker 线程上执行并立即返回。可以使用 get 方法等待 SwingWorker 完成。
Worker 线程:在此线程上调用 doInBackground() 方法。所有后台活动都应该在此线程上发生。要通知 PropertyChangeListeners 有关绑定 (bound) 属性的更改,请使用 firePropertyChange 和 getPropertyChangeSupport() 方法。默认情况下,有两个可用的绑定属性:state 和 progress。
事件指派线程:所有与 Swing 有关的活动都在此线程上发生。SwingWorker 调用 process 和 done() 方法,并通知此线程的所有 PropertyChangeListener。
通常,当前 线程就是事件指派线程。
在 worker 线程上调用 doInBackground 方法之前,SwingWorker 通知所有 PropertyChangeListener 有关