JDK-6190373 : REGRESSION: AWT-EventQueue Deadlock AWTTreeLock/MetalUtils$GradientPainter
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2004-11-03
  • Updated: 2010-12-06
  • Resolved: 2005-08-03
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
5.0u11Fixed 6 b46Fixed
Description
In a stress test with customer's application creating and closing multiple applets, the swing deadlock is observed with J2SE 5.0 FCS. Two AWT EventQueue threads are deadlocked. The full java thread dump is also attached to this bug report.

Deadlock Information (see attachments for full thread dump): 

Found one Java-level deadlock:
=============================
"AWT-EventQueue-4":
  waiting to lock monitor 0x06b231dc (object 0x1170ad00, a javax.swing.plaf.meta
l.MetalUtils$GradientPainter),
  which is held by "AWT-EventQueue-3472"
"AWT-EventQueue-3472":
  waiting to lock monitor 0x02d79b44 (object 0x109e7c38, a java.awt.Component$AW
TTreeLock),
  which is held by "AWT-EventQueue-4"

Java stack information for the threads listed above:
===================================================
"AWT-EventQueue-4":
        at javax.swing.plaf.metal.MetalUtils$GradientPainter.paint(MetalUtils.ja
va:239)
        - waiting to lock <0x1170ad00> (a javax.swing.plaf.metal.MetalUtils$Grad
ientPainter)
        at javax.swing.plaf.metal.MetalUtils.drawGradient(MetalUtils.java:203)
        at javax.swing.plaf.metal.MetalScrollBarUI.oceanPaintThumb(MetalScrollBa
rUI.java:344)
        at javax.swing.plaf.metal.MetalScrollBarUI.paintThumb(MetalScrollBarUI.j
ava:212)
        at javax.swing.plaf.basic.BasicScrollBarUI.paint(BasicScrollBarUI.java:3
64)
        at javax.swing.plaf.ComponentUI.update(ComponentUI.java:142)
        at javax.swing.JComponent.paintComponent(JComponent.java:740)
        at javax.swing.JComponent.paint(JComponent.java:1003)
        at javax.swing.JComponent.paintChildren(JComponent.java:840)
        - locked <0x109e7c38> (a java.awt.Component$AWTTreeLock)
        at javax.swing.JComponent.paint(JComponent.java:1012)
        at javax.swing.JComponent.paintChildren(JComponent.java:840)
        - locked <0x109e7c38> (a java.awt.Component$AWTTreeLock)
        at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4937)

        at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4883)
        at javax.swing.JComponent.paint(JComponent.java:993)
        at javax.swing.JComponent.paintChildren(JComponent.java:840)
        - locked <0x109e7c38> (a java.awt.Component$AWTTreeLock)
        at javax.swing.JComponent.paint(JComponent.java:1012)
        at javax.swing.JViewport.paint(JViewport.java:728)
        at javax.swing.JComponent.paintChildren(JComponent.java:840)
        - locked <0x109e7c38> (a java.awt.Component$AWTTreeLock)
        at javax.swing.JComponent.paint(JComponent.java:1012)
        at jp.co.yokogawa.Stardom.UD.client.Message.CSDUDGRMessage.draw(CSDUDGRM
essage.java:609)
        at jp.co.yokogawa.Stardom.UD.client.Message.CSDUDGrMsgAlarm.draw(CSDUDGr
MsgAlarm.java:429)
        at jp.co.yokogawa.Stardom.UD.client.GrObjWnd.CSDUDPrimitiveList.allDraw(
CSDUDPrimitiveList.java:141)
        at jp.co.yokogawa.Stardom.UD.client.GrObjWnd.CSDUDGrObjWnd.paint(CSDUDGr
ObjWnd.java:713)
        at jp.co.yokogawa.Stardom.UD.client.GrObjWnd.CSDUDGrObjWnd.update(CSDUDG
rObjWnd.java:681)
        at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
        at sun.awt.RepaintArea.paint(RepaintArea.java:216)
        at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:254)
        at java.awt.Component.dispatchEventImpl(Component.java:4031)
        at java.awt.Container.dispatchEventImpl(Container.java:2024)
        at java.awt.Component.dispatchEvent(Component.java:3803)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:234)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:163)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)

        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)

        at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)
"AWT-EventQueue-3472":
        at java.awt.Component.getGraphicsConfiguration(Component.java:814)
        - waiting to lock <0x109e7c38> (a java.awt.Component$AWTTreeLock)
        at javax.swing.plaf.metal.CachedPainter.paint(CachedPainter.java:68)
        at javax.swing.plaf.metal.MetalUtils$GradientPainter.paint(MetalUtils.ja
va:249)
        - locked <0x1170ad00> (a javax.swing.plaf.metal.MetalUtils$GradientPaint
er)
        at javax.swing.plaf.metal.MetalUtils.drawGradient(MetalUtils.java:203)
        at javax.swing.plaf.metal.MetalButtonUI.update(MetalButtonUI.java:110)
        at javax.swing.JComponent.paintComponent(JComponent.java:740)
        at javax.swing.JComponent.paint(JComponent.java:1003)
        at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4930)

        at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4883)
        at javax.swing.JComponent._paintImmediately(JComponent.java:4826)
        at javax.swing.JComponent.paintImmediately(JComponent.java:4633)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:451)

        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(System
EventQueueUtilities.java:114)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:234)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:163)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:153)
        at java.awt.Dialog$1.run(Dialog.java:515)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:234)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:163)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:153)
        at java.awt.Dialog$1.run(Dialog.java:515)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:234)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:163)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:153)
        at java.awt.Dialog$1.run(Dialog.java:515)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:234)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:163)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:153)
        at java.awt.Dialog$1.run(Dialog.java:515)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:234)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:163)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)

        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)

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

Found 1 deadlock.
###@###.### 11/3/04 22:15 GMT

Comments
EVALUATION Yep, this is definitely a yucky one. There are a couple of possible solutions to this. I have to decide what the best approach is. ###@###.### 2005-07-12 19:27:52 GMT It turns out there are two problems with CachedPainter. The first one is that it's possible to deadlock. Here's the sequence that this test case is triggering: Applet1 paint paintChildren treelock sync MetalUtils.paint get image to paint to grab tree lock Applet2 paint sync MetalUtils.paint get image grab tree lock As you can see the lock from MetalUtils and the tree lock are not grabbed in the same order, leading to the dead lock. The fix is to have MetalUtils synchronize on the tree lock, not on itself. The second problem is that it's possible for two threads to use the same image. This can be problematic if the image has been invalidated. One thread will see it as invalid and paint to it, the other will see as valid when it really isn't. The fix for this is to have CachedPainter also synchronize on the tree lock. ###@###.### 2005-07-18 20:48:29 GMT
12-07-2005