Swing与多线程-小结

来源:互联网 发布:有什么软件程序 编辑:程序博客网 时间:2024/04/30 22:30

(1)如果要在图形界面上显示经过数据查询或经过其他方式得来的数据,一般将这个过程放在一个线程中,由该线程进行单独运算,并随时更新图形界面。

(2)Swing线程发生死锁的时候,如果是使用命令行的方式运行的该程序,可以使用CTRL+BREAK的快捷键,会得到线程死锁的位置,堆栈的一些信息。

(3)只有与Swing相同的线程才能对Swing中的组件进行调用,修改等,如ActionListener中的处理就是与Swing保持在同一个线程侯中,不在同一个线程时,需使用SwingUtilities.invokeLater()。但需注意的是invokeLater在工作时都会使Swing主线程的窗口绘制工作停下了,直到invokeLater结束,所以在invokeLater中不要做一些耗时的工作,尽量只做与界面更新相关的工作。 SwingUtilities.isEventDispatchThread():return true if the current thread is an awt event dispatching thread.该方法可以判断当前线程是否awt事件线程,如果不是对于界面的更新操作就应放在invokeLater中。

(4)Swing是一个基于事件队列的单线程模型,GUI上的事件,一个个依次awt event dispatching thread执行,不会发生抢夺资源的情况。这个事件队列就是java.awt.EventQueue.EventQueue is a platform-dependent class that queues event, both from the underlying peer classes and from the trusted application classes. It encapsulates asychronousevent dispatch machinary which extracts events from the queue and dispatch them by calling dispatchEvent(AWTEvent) method on this EventQueue with the event to be dispatched  as an argument. The requriements for the events are:Sequentially, that is, it s not permited that serveral events are dispatched simoultanously and the order to be dispatched should be as they are enqueued. And the awt event dispatching thread is fired by the envent dispatch machinary.InvokeLater(Runnable doRun) method causes the doRun.run() to be executed asynchronously on AWT Event dispatch thread, and this will happen after all pending AWT events have been processed. This method should be used when an application thread needs to update the GUI.InvokeAndWait(Runnable doRun) method causes the doRun.run() to be executed sychronously on the AWT event dispatch thread,and this call block uitil all pending AWT events have been processed and then doRun.run() returns.

(5)比如要在一个按钮上又一个操作耗费时间较多,应将此业务代码放在一个线程中执行,执行完毕后再在Dispatch Thread执行Swing组件更新代码。下文中使用SwingWorker在1.6中已经存在,1.5的可以到https://swingworker.dev.java.net/下载。注意这里不能使用invokeLater,应创建一个线程类或使用SwingWorker

 (6)在进行Swing开发时遇到一个异常: Exception in thread "Thread-5" java.lang.ClassCastException: sun.java2d.NullSurfaceData cannot be cast to    sun.java2d.d3d.D3DSurfaceData
 at sun.java2d.d3d.D3DRenderer.copyArea(Unknown Source)
 at sun.java2d.d3d.D3DSurfaceData.copyArea(Unknown Source)
 at sun.java2d.SunGraphics2D.doCopyArea(Unknown Source)
 at sun.java2d.SunGraphics2D.copyArea(Unknown Source)
 at javax.swing.BufferStrategyPaintManager.copyArea(Unknown Source) 到网络上搜索也没有找到确切答案,但是根据以上原则,发现自己确实违反了一点,在一个线程中直接调用table的更新操作,之后将该table的更新操作放到invokeLater中,后来就没有了