On Fri, Jul 04, 2003 at 09:12:18AM -0500, Bill Hibbard wrote: ... > > By tracing with the universal debugging tool (System.out.println()) I > > can see that one VisAD thread is in ActionImpl.run(), synchronized on > > lockEnabled, and an AWT thread (presumably from > > SwingUtilities.invokeLater()) is waiting to synchronize in the same > > place. The VisAD thread does not leave the synchronized block, it gets > > to DisplayRenderer.prepareAction(), calls map.setRange(shadow) where map > > is a ScalarMap (Time->DisplayAnimation) and hangs there. ... > I can't find any deadlock by inspection. ScalarMap.setRange() for > a ScalarMap (Time->DisplayAnimation) calls AnimationControl.setSet(), > which calls AnimationSetControl.setSet(), which calls > Control.changeControl(), which does 'synchronized (ListenerVector)', > but it hard to see how your code in the AWT Thread can be holding > a lock on ListenerVector in Control. Found it. We have a class elsewhere in the app that implements ControlListener, and listens to AnimationControl events. That class updates swing components with invokeAndWait(). So we have a swing thread wanting to do VisAD stuff and a VisAD thread wanting to do swing stuff. Deadlock. Now I have to think about some redesign in there. > A very good way to find deadlocks is to run under jdb. When it hangs, > do a 'suspend all' and then a 'where all', which will dump the call > stack for all Threads. You should be able to spot the deadlock by > examining the locks held by the two hung Threads. I'd be happy to > take a look at the output of 'where all'. Thanks for this advice, Bill. jdb showed me exactly what was going on. Russell -- Russell Steicke -- Fortune says: Freedom from incrustation of grime is contiguous to rectitude.