Java多线程之"事件分发线程"----Event Dispatch Thread

当运行GUI小程序(Applet)或应用程序(Application)时,main()方法中的代码会建立一个GUI并设置事件句柄.当调用Frame,Dialog,Window的setVisible(true)或浏览器显示Applet时,我们就是在和GUI交互. 

问题是你的main()可能不会只停留在用户界面上,它可能会作一些其他方法.比如计算PI直到小数点后40000位.如果用户在和GUI交互之前要等待一段漫长的时间的话,他们可能就会退出。

  所以AWT库实现了监控GUI交互的线程.这个线程实际上就是循环检查系统事件队列(System Event Queue)是否有鼠标点击,键盘按下或其他系统事件(也可以把自己的事件加入系统事件队列,这就是将在下一片中提到的).这个线程就是事件分发线程(Event Dispatch Thread),它是java.awt.EventDispatchThread的一个实例.事件分发线程是Swing和AWT中最重要的,在绘制,更新和显示组件和受控的应用程序方面扮演这关键的角色.和这个线程紧密相关的是一个FIFO事件的队列----系统事件队列,它是java.awt.EventQueue的一个实例.每个事件都是按顺序一个一个的执行的,这是为了避免在组件重绘的过程中组件的状态发生变化.我们一定要小心不要再事件分发线程之外分发一个事件.例如,在另外执行的线程中直接调用fireXX()方法是不安全的.另外,应当尽量使事件句柄和绘制方法尽可能的短小精悍,否则系统的反应会变得不灵敏,有些时候甚至看起来象是死机了. 

  事件分发线程(Event Dispatch Thread)从系统事件队列取出并检测对其采取何种处理.如果是对一个组件的点击,就为这个组件调用处理句柄.接下来,那个组件再发送其他事件.例如,假设你单击了一个JButton,事件分发线程传递一个鼠标单击到JButton, JButton把它解释成一个"按钮按下",并调用它的actionPerformed方法.所有注册过的监听器的actionPerformed方法都会得到调用. 

  javax.swing.EventLisenerList是一个包含XXEvent/XXListener对的数组.所有的组件(JComponent)和模型(model)都有自己的EventListenerList数组.当Listener被加入或删除的时候,新的EventListenerList数组会通过System.arrayCopy()被创建.之所以不使用Vector而代之以数组是因为考虑到执行效率的原因. 

  AWT线程(事件分发线程)也负责GUI的重绘.任何时候调用了repaint方法,一个刷新请求就被放入事件队列.只要AWT线程看到刷新请求,它就会检查GUI的破坏区和被标记为invalid的组件,然后调用适当的方法输出GUI和需要重绘的组件.  

  所有的AWT组件都是线程安全的,在线程安全的方式下,当你调用一个Label的setText()方法时,显示是同步的,你不会看到一半是老的内容一半是新的内容的情况.而swing组件不是线程安全的.你必须确保任何对组件的更改都通过事件分发线程处理.如果一个线程即更新又显示一个组件,你必须保证他们的一致性.:-) 

Please wait for the next article :   

Java多线程之建立自己的线程安全方法----Build Our Own Thread-safe Methods 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章