I have a Gui application in swing that prints a ticket on a serial thermal printer. When i hit the button that launch this action, my GUI is frozen. I think that's because the code is executed on the EDT. I used jstack to be sure but i don't understand the results below :
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
Can someone explain to me where i can see that my GUI is frozen because of the first thread "Thread-12".
And secondly what's the difference between "Thread-6" and "Thread-7" as long as I'm sure i only ran this thread once.
AWT-EventQueue-0
is your event dispatch thread, and it is indeed blocked reading from a serial port via a socket via RXTX
hsqldb
. You should use SwingWorker
, as suggested by @Kumar. Examples may be found here and here. I found it helpful to examine such examples in a profiler for study.
Thread-6
and Thread-7
appear to belong to your application as instances of Threads.ThreadHorloge
in posO2
. Regarding thread names:
Every thread has a name for identification purposes. More than one thread may have the same name. If a name is not specified when a thread is created, a new name is generated for it.
Note that SwingWorker
and Executors
typically include the text pool-n, where n is a sequence number.
Addendum: My EDT is in a RUNNABLE
state, so from the code I pasted where do you figure out that it's blocked; and where do you find that the reading via RXTX is the blocking cause?
Sorry, my mistake; corrected above. The EDT isn't BLOCKED
in the Thread.STATE
sense of waiting for a monitor lock; it's blocked in the sense that it's waiting for the database to respond, at least long enough to be seen atop the call stack when you send the -QUIT
signal. Neither serial nor network operations should be scheduled on the EDT.
One very basic rule:
This way we can keep the GUI interactive and responsive.
In Java Event Dispatcher Thread (EDT) is the UI thread, main()
method in Java GUI application is not long lived, so after scheduling the work of GUI construction in the Event Dispatcher Queue it quits and then it's EDT that handles the GUI.
Either use Thread
to do the Long Non-UI processing work, or use SwingWorker
, this is provided in java to do a seamless synchronization between the UI and Non-UI work......
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With