2

I'm getting a deadlock in the Swing application I maintain, and although I have a workaround that appears to work, I'm not sure that I have understood what I am doing and haven't just hidden a race condition that may pop up again later.

A thread trace shows the deadlock is occurring between two threads, AWT-EventQueue-0 and AWT-EventQueue-1. My first question is which if either of these is the infamous Event Dispatching Thread. Both threads have the following at the bottom of their stack trace:

at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)

I think the root of the problem is that the application classes mix domain data with graphical components, and in this case both threads are trying to lock both a java.awt.Component$AWTTreeLock and one of my own objects (say X). My workaround is to use SwingUtilities.invokeLater() in one place where X is locked, even though this is already on the EDT. According to the Javadoc this means the call "deferred until all pending events have been processed". However, I'm not quite sure that this is really a solution, and in any case I'm unclear why there seem to be two EDTs.

Can anyone explain what is going on? I can try to provide a cut-down version of the code but it may take me a while to edit out the irrelevant complications.

Ben
  • 2,348
  • 2
  • 19
  • 28
  • 2
    Do you open a modal dialog in this process? Or does your code push a new Queue? – Yishai Mar 20 '12 at 21:59
  • Ah, yes! I'll have to look at how that works. Doesn't it replace the existing queue? Why would it result in two AWT-EventQueue threads? – Ben Mar 20 '12 at 22:22

2 Answers2

1

Thanks to Yishai for pointing me in the right direction. The application is instantiating its own subclass of java.awt.EventQueue and using Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQueue) to replace the original queue. The original queue must still be processing a task on its thread, AWT-EventQueue-0 at the same time as events start arriving in the new queue on thread AWT-EventQueue-1, resulting in deadlock.

Ben
  • 2,348
  • 2
  • 19
  • 28
0

Are you creating threads anywhere? If yes, consider to use

http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html

or

http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html

instead which work well with Swing.

Puce
  • 37,247
  • 13
  • 80
  • 152
  • No, not explicitly creating any new threads. Just some initialization the main thread (some of which I have moved to the EDT using invokeLater) and the event handlers for the Swing components, which of course are called on the EDT. That is how it is supposed to be anyway. – Ben Mar 20 '12 at 22:36