Java Swing:GUI冻结 – jstack解释

我有一个Gui应用程序,可以在串行热敏打印机上打印票据。 当我点击启动此操作的按钮时,我的GUI被冻结。 我认为那是因为代码是在EDT上执行的。 我使用jstack确定但我不理解下面的结果:

Full thread dump Java HotSpot(TM) Client VM (23.3-b01 mixed mode, sharing): "Thread-12" prio=6 tid=0x03012000 nid=0xd04 runnable [0x038ef000] java.lang.Thread.State: RUNNABLE at gnu.io.RXTXPort.eventLoop(Native Method) at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1575) "Thread-6" prio=6 tid=0x0302c400 nid=0x1b0 waiting on condition [0x039ef000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at posO2.Threads.ThreadHorloge.run(ThreadHorloge.java:46) "Thread-5" prio=6 tid=0x03511c00 nid=0x9e4 waiting on condition [0x0399f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at posO2.Threads.ThreadIgor.run(ThreadIgor.java:29) "Thread-7" prio=6 tid=0x034b9800 nid=0xb40 waiting on condition [0x0394f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at posO2.Threads.ThreadHorloge.run(ThreadHorloge.java:46) at java.lang.Thread.run(Unknown Source) "Thread-4" prio=6 tid=0x0318ec00 nid=0xa08 waiting on condition [0x0323f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at posO2.Threads.ThreadMajProduits.run(ThreadMajProduits.java:49) "TimerQueue" daemon prio=6 tid=0x03036400 nid=0x9b8 waiting on condition [0x0344 f000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for  (a java.util.concurrent.locks.Abstra ctQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(Unknown Source) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject .await(Unknown Source) at java.util.concurrent.DelayQueue.take(Unknown Source) at javax.swing.TimerQueue.run(Unknown Source) at java.lang.Thread.run(Unknown Source) "DestroyJavaVM" prio=6 tid=0x003c8400 nid=0xfe4 waiting on condition [0x00000000 ] java.lang.Thread.State: RUNNABLE "AWT-EventQueue-0" prio=6 tid=0x02b6e000 nid=0xcbc runnable [0x033fe000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(Unknown Source) at java.net.SocketInputStream.read(Unknown Source) at java.io.BufferedInputStream.fill(Unknown Source) at java.io.BufferedInputStream.read(Unknown Source) - locked  (a java.io.BufferedInputStream) at java.io.DataInputStream.readByte(Unknown Source) at org.hsqldb.result.Result.newResult(Unknown Source) at org.hsqldb.ClientConnection.read(Unknown Source) at org.hsqldb.ClientConnection.execute(Unknown Source) - locked  (a org.hsqldb.ClientConnection) at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source) at org.hsqldb.jdbc.JDBCStatement.executeQuery(Unknown Source) - locked  (a org.hsqldb.jdbc.JDBCStatement) at posO2.Printer.flash(Printer.java:1058) at posO2.Printer.bigFlash(Printer.java:1111) at posO2.Panels.Accueil$5.actionPerformed(Accueil.java:314) at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) at javax.swing.DefaultButtonModel.setPressed(Unknown Source) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) at java.awt.Component.processMouseEvent(Unknown Source) at javax.swing.JComponent.processMouseEvent(Unknown Source) at java.awt.Component.processEvent(Unknown Source) at java.awt.Container.processEvent(Unknown Source) at java.awt.Component.dispatchEventImpl(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.awt.Container.dispatchEventImpl(Unknown Source) at java.awt.Window.dispatchEventImpl(Unknown Source) at java.awt.Component.dispatchEvent(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$200(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.awt.EventQueue$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.awt.EventQueue$4.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) "AWT-Shutdown" prio=6 tid=0x02b81800 nid=0xefc in Object.wait() [0x033af000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on  (a java.lang.Object) at java.lang.Object.wait(Object.java:503) at sun.awt.AWTAutoShutdown.run(Unknown Source) - locked  (a java.lang.Object) at java.lang.Thread.run(Unknown Source) "AWT-Windows" daemon prio=6 tid=0x03002800 nid=0xe58 runnable [0x0328f000] java.lang.Thread.State: RUNNABLE at sun.awt.windows.WToolkit.eventLoop(Native Method) at sun.awt.windows.WToolkit.run(Unknown Source) at java.lang.Thread.run(Unknown Source) "Java2D Disposer" daemon prio=10 tid=0x03000400 nid=0x4d0 in Object.wait() [0x03 1ef000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on  (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) - locked  (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) at sun.java2d.Disposer.run(Unknown Source) at java.lang.Thread.run(Unknown Source) "Service Thread" daemon prio=6 tid=0x02b63000 nid=0xb94 runnable [0x00000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread0" daemon prio=10 tid=0x02b54c00 nid=0x3f0 waiting on conditio n [0x00000000] java.lang.Thread.State: RUNNABLE "Attach Listener" daemon prio=10 tid=0x02b53400 nid=0x924 waiting on condition [ 0x00000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" daemon prio=10 tid=0x02b52000 nid=0xb88 runnable [0x00000000 ] java.lang.Thread.State: RUNNABLE "Finalizer" daemon prio=8 tid=0x02b43c00 nid=0xfc8 in Object.wait() [0x02dff000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on  (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) - locked  (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source) "Reference Handler" daemon prio=10 tid=0x02b3f000 nid=0x488 in Object.wait() [0x 02daf000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on  (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:503) at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source) - locked  (a java.lang.ref.Reference$Lock) "VM Thread" prio=10 tid=0x02b3d400 nid=0xa6c runnable "VM Periodic Task Thread" prio=10 tid=0x02b76800 nid=0xf30 waiting on condition JNI global references: 426 

有人可以向我解释我在哪里可以看到我的GUI因第一个线程“Thread-12”而被冻结。

其次,“Thread-6”和“Thread-7”之间的区别是什么,只要我确定我只运行了一次该线程。

AWT-EventQueue-0是你的事件调度线程,它确实被阻止从串口通过RXTX读取一个套接字通过hsqldb 。 你应该按照@Kumar的建议使用SwingWorker 。 可以在这里和这里找到示例。 我发现在剖析器中研究这样的例子是有帮助的。

Thread-6Thread-7似乎属于你的应用程序,作为Threads.ThreadHorlogeposO2实例。 关于线程名称:

每个线程都有一个用于识别目的的名称。 多个线程可能具有相同的名称。 如果在创建线程时未指定名称,则会为其生成新名称。

请注意, SwingWorkerExecutors通常包含文本池-n ,其中n是序列号。

附录: 我的EDT处于 RUNNABLE 状态,所以从我粘贴的代码中你在哪里发现它被阻止了; 你在哪里发现通过RXTX的读数是阻塞原因

抱歉,是我的错; 以上更正。 在等待监视器锁定的Thread.STATE意义上,EDT没有被阻塞; 它在等待数据库响应的意义上被阻止,至少足以在发送-QUIT信号时在调用堆栈顶部看到-QUIT 。 在EDT上不应安排串行或网络操作。

一个非常基本的规则:

  • 保持UI工作在UI线程上,非UI工作在非UI线程上。

这样我们就可以保持GUI的交互性响应性

  • 在Java 事件调度程序线程(EDT)是UI线程,Java GUI应用程序中的main()方法不长,因此在调度事件调度程序队列中的GUI构造工作后,它退出然后它处理GUI的EDT。

  • 要么使用Thread做Long Non-UI处理工作,要么使用SwingWorker ,这是在java中提供的UI和非UI工作之间做无缝同步……

该线程是从事件队列启动的线程

“AWT-EventQueue-0”prio = 6 tid = 0x02b6e000 nid = 0xcbc runnable [0x033fe000] java.lang.Thread.State:RUNNABLE

你可以说,因为在这个步骤的堆栈跟踪的最后,它是由EventDispatchThread启动的:

at java.awt.EventDispatchThread.run(Unknown Source)

至于你的问题“线程6和线程7之间有什么区别”,我没有直接回答你,但我认为这些线程中的大部分都是由你的探查器创建的(因此你就是这样)看到它是旋转的线程)。 虽然可能是错的。 我无法在Threads.ThreadHorloge类中找到它随便引用的任何内容。