【问题标题】:Java Swing : GUI frozen - jstack interpretationJava Swing : GUI 冻结 - jstack 解释
【发布时间】:2012-09-25 13:36:52
【问题描述】:

我有一个正在使用的 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  <0x27e76778> (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 <0x22f33f30> (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 <0x22f32700> (a org.hsqldb.ClientConnection)
    at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
    at org.hsqldb.jdbc.JDBCStatement.executeQuery(Unknown Source)
    - locked <0x22be23b0> (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 <0x27c707c0> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:503)
    at sun.awt.AWTAutoShutdown.run(Unknown Source)
    - locked <0x27c707c0> (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 <0x27c2bf18> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(Unknown Source)
    - locked <0x27c2bf18> (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 <0x27c2c148> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(Unknown Source)
    - locked <0x27c2c148> (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 <0x27c2bdd8> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:503)
    at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
    - locked <0x27c2bdd8> (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”之间有什么区别,只要我确定我只运行过这个线程一次。

【问题讨论】:

  • 打印调用是否阻塞?如果是阻塞调用,只需将其委托给不同的线程即可。

标签: java multithreading swing event-dispatch-thread jstack


【解决方案1】:

AWT-EventQueue-0 是您的事件调度线程,它确实被阻止通过RXTX串行端口读取通过hsqldb 的套接字。正如@Kumar 所建议的,您应该使用SwingWorker。可以在herehere 中找到示例。我发现在 profiler 中检查此类示例以供学习很有帮助。

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

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

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

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

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

【讨论】:

  • 好的,谢谢,但它说我的 EDT 处于可运行状态,所以从我粘贴的代码中,你发现它在哪里被阻塞,你在哪里发现通过 RXTX 读取是阻塞的原因?
【解决方案2】:

一个非常基本的规则:

  • 让 UI 在 UI 线程上工作,而 Non-UI 在 Non-UI 线程上工作。

这样我们可以保持 GUI 交互式响应式

  • 在Java中Event Dispatcher Thread (EDT)是UI线程,main()方法在Java GUI应用中的寿命并不长,所以在调度GUI构建工作之后在Event Dispatcher Queue 它退出,然后由 EDT 处理 GUI。

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

【讨论】:

    【解决方案3】:

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

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

    你可以看出来,因为在这个线程的堆栈跟踪的最后,它是由 EventDispatchThread 启动的:

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

    至于您关于“线程 6 和线程 7 有什么区别”的问题,我没有直接的答案,但我认为这些线程中的大多数是由您的分析器创建的(那么你看到的是它旋转起来的线程)。但这可能是错误的。我在它临时引用的 Threads.ThreadHorloge 类上找不到任何东西。

    【讨论】:

      猜你喜欢
      • 2012-06-26
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多