-
Bug
-
Resolution: Fixed
-
P3
-
1.4.1, 1.4.2_03
-
b41
-
x86, sparc
-
solaris_8, windows_nt
Name: jk109818 Date: 03/25/2003
FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
FULL OPERATING SYSTEM VERSION :
Windows NT Version 4.0 SP5
A DESCRIPTION OF THE PROBLEM :
Animated images can cause the AWT-EventQueue thread to
deadlock with the "Image Animator" thread.
This issue is new to 1.4.1_x and did NOT occur on 1.4.0_x.
The provided snippet appears somewhat constructed since the
deadlock is hard to reproduce. However, it does resemble
what our application is doing "in the real world". We see
the excact same problem in our production code.
The deadlock appears in 1.4.1_x and not in 1.4.0_x because
1.4.1_x's RepaintManager.addDirtyRegion(..) contains a new
call to Frame.getExtendedState(). However, IMHO the root of
the problem is in Image Animator.
Since the sources of the sun.awt.* classes are not
available (aren't they?) one (i.e. I) can only guess.
Looking at the stack trace it appears that the Image
Animator violates Swing's single-thread-rule.
Both the AWT-EventQueue and the Image Animator eventually
call RepaintManager.addDirtyRegion, which is synchronized
on the RepaintManager.
RepaintManager.addDirtyRegion (since 1.4.1_x) calls
Frame.getExtendedState which grabs the Frame's monitor. The
deadlock occurs if the second thread is waiting for
addDirtyRegion's RepaintManager monitor while it happens to
own the Frame monitor. Note the "synchronized(frame)" block
in my snippet.
Our production code uses a JFrame subclass with
synchronized methods instead...
BTW - bug 4480705 seems somewhat related in that it was
apparently also caused by the Image Animator thread
violating Swing's single-thread-rule.
REGRESSION. Last worked in version 1.4
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. run the provided test application
2. wait
3. if no deadlock accurs: wait even longer ;-)
4. still no deadlock? Randomly switching OS tasks seems to
increase the likelihood of the deadlock to occur on my
machine
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Full thread dump Java HotSpot(TM) Client VM (1.4.1_01-b01 mixed mode):
"Image Animator 0" daemon prio=4 tid=0x007D1390 nid=0x145 waiting for monitor en
try [b72f000..b72fd90]
at java.awt.Frame.getExtendedState(Frame.java:729)
- waiting to lock <030B3830> (a javax.swing.JFrame)
at javax.swing.RepaintManager.addDirtyRegion(RepaintManager.java:265)
- locked <030C6A08> (a javax.swing.RepaintManager)
at javax.swing.JComponent.repaint(JComponent.java:4333)
at java.awt.Component.imageUpdate(Component.java:2618)
at javax.swing.JLabel.imageUpdate(JLabel.java:881)
at sun.awt.image.ImageWatched.newInfo(ImageWatched.java:55)
at sun.awt.image.ImageRepresentation.imageComplete(ImageRepresentation.j
ava:636)
at sun.awt.image.ImageDecoder.imageComplete(ImageDecoder.java:135)
at sun.awt.image.GifFrame.dispose(GifImageDecoder.java:670)
at sun.awt.image.GifImageDecoder.readImage(GifImageDecoder.java:477)
at sun.awt.image.GifImageDecoder.produceImage(GifImageDecoder.java:220)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.j
ava:257)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:168)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
"DestroyJavaVM" prio=5 tid=0x00794EA0 nid=0x199 waiting on condition [0..6fadc]
"Thread-3" daemon prio=5 tid=0x00793B30 nid=0x1c7 in Object.wait() [b58f000..b58
fd90]
at java.lang.Object.wait(Native Method)
- waiting on <030EC590> (a java.util.TaskQueue)
at java.util.TimerThread.mainLoop(Timer.java:429)
- locked <030EC590> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:382)
"Thread-2" daemon prio=5 tid=0x00793DB0 nid=0x1b5 in Object.wait() [b54f000..b54
fd90]
at java.lang.Object.wait(Native Method)
- waiting on <030EC5F8> (a java.util.TaskQueue)
at java.util.TimerThread.mainLoop(Timer.java:429)
- locked <030EC5F8> (a java.util.TaskQueue)
at java.util.TimerThread.run(Timer.java:382)
"AWT-EventQueue-0" prio=7 tid=0x00791290 nid=0x16b waiting for monitor entry [b5
0f000..b50fd90]
at javax.swing.RepaintManager.addDirtyRegion(RepaintManager.java:234)
- waiting to lock <030C6A08> (a javax.swing.RepaintManager)
at javax.swing.JComponent.repaint(JComponent.java:4333)
at java.awt.Component.repaint(Component.java:2453)
at javax.swing.JComponent.setVisible(JComponent.java:2211)
at com.borland.samples.welcome.AnimatorDeadlock$1.run(AnimatorDeadlock.j
ava:21)
- locked <030B3830> (a javax.swing.JFrame)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:197)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)
"Java2D Disposer" daemon prio=10 tid=0x0078F7F0 nid=0x134 in Object.wait() [b4cf
000..b4cfd90]
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
- locked <030EC728> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
at sun.java2d.Disposer.run(Disposer.java:97)
at java.lang.Thread.run(Thread.java:536)
"AWT-Windows" daemon prio=7 tid=0x00785440 nid=0x1ba runnable [b02f000..b02fd90]
at sun.awt.windows.WToolkit.eventLoop(Native Method)
at sun.awt.windows.WToolkit.run(WToolkit.java:253)
at java.lang.Thread.run(Thread.java:536)
"AWT-Shutdown" prio=5 tid=0x00785850 nid=0x19c in Object.wait() [afef000..afefd9
0]
at java.lang.Object.wait(Native Method)
- waiting on <030B3808> (a java.lang.Object)
at java.lang.Object.wait(Object.java:426)
at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:259)
- locked <030B3808> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:536)
"Signal Dispatcher" daemon prio=10 tid=0x0076C210 nid=0x1b4 waiting on condition
[0..0]
"Finalizer" daemon prio=9 tid=0x00768280 nid=0x198 in Object.wait() [acaf000..ac
afd90]
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
- locked <030587D0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=10 tid=0x00767180 nid=0x13c in Object.wait() [ac
6f000..ac6fd90]
at java.lang.Object.wait(Native Method)
- waiting on <03058838> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:426)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:113)
- locked <03058838> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=5 tid=0x00766470 nid=0x1c9 runnable
"VM Periodic Task Thread" prio=10 tid=0x0076B770 nid=0x1b8 waiting on condition
"Suspend Checker Thread" prio=10 tid=0x0076B110 nid=0x1c8 runnable
Found one Java-level deadlock:
=============================
"Image Animator 0":
waiting to lock monitor 0xa5a32c (object 0x30b3830, a javax.swing.JFrame),
which is held by "AWT-EventQueue-0"
"AWT-EventQueue-0":
waiting to lock monitor 0xa5a30c (object 0x30c6a08, a javax.swing.RepaintManag
er),
which is held by "Image Animator 0"
Java stack information for the threads listed above:
===================================================
"Image Animator 0":
at java.awt.Frame.getExtendedState(Frame.java:729)
- waiting to lock <030B3830> (a javax.swing.JFrame)
at javax.swing.RepaintManager.addDirtyRegion(RepaintManager.java:265)
- locked <030C6A08> (a javax.swing.RepaintManager)
at javax.swing.JComponent.repaint(JComponent.java:4333)
at java.awt.Component.imageUpdate(Component.java:2618)
at javax.swing.JLabel.imageUpdate(JLabel.java:881)
at sun.awt.image.ImageWatched.newInfo(ImageWatched.java:55)
at sun.awt.image.ImageRepresentation.imageComplete(ImageRepresentation.j
ava:636)
at sun.awt.image.ImageDecoder.imageComplete(ImageDecoder.java:135)
at sun.awt.image.GifFrame.dispose(GifImageDecoder.java:670)
at sun.awt.image.GifImageDecoder.readImage(GifImageDecoder.java:477)
at sun.awt.image.GifImageDecoder.produceImage(GifImageDecoder.java:220)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.j
ava:257)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:168)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
"AWT-EventQueue-0":
at javax.swing.RepaintManager.addDirtyRegion(RepaintManager.java:234)
- waiting to lock <030C6A08> (a javax.swing.RepaintManager)
at javax.swing.JComponent.repaint(JComponent.java:4333)
at java.awt.Component.repaint(Component.java:2453)
at javax.swing.JComponent.setVisible(JComponent.java:2211)
at com.borland.samples.welcome.AnimatorDeadlock$1.run(AnimatorDeadlock.j
ava:21)
- locked <030B3830> (a javax.swing.JFrame)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:197)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)
Found 1 deadlock.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.util.*;
import javax.swing.*;
public class AnimatorDeadlock {
public static void main(String[] args) {
final JFrame frame = new JFrame("AnimatorDeadlock");
final JLabel lblAnimator = new JLabel(new ImageIcon(
AnimatorDeadlock.class.getResource("animated.gif")));
frame.setGlassPane(new JLabel("I am the glassPane"));
frame.getContentPane().add(lblAnimator, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
startTimer(134, new Runnable() {
public void run() {
synchronized(frame) {
Component c = frame.getGlassPane();
c.setVisible(!c.isVisible());
}
}
});
startTimer(50, new Runnable() {
public void run() {
lblAnimator.setVisible(!lblAnimator.isVisible());
}
});
}
private static void startTimer(int pause, final Runnable guiAction) {
java.util.Timer timer = new java.util.Timer(true);
TimerTask task = new TimerTask() {
public void run() {
SwingUtilities.invokeLater(guiAction);
}
};
timer.scheduleAtFixedRate(task, 0, pause);
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Don't synchronize on Frame instances. If you have Frame
subclasses with synchronized methods rewrite them to use a
explicit synchronisation monitor, e.g.
private Object _monitor = new Object();
...
public foo() {
synchronized(_monitor) {
...
}
}
instead of just
public synchronized foo() {
...
}
(Review ID: 166471)
======================================================================
- duplicates
-
JDK-4983070 AbstractTableModel.fireTableRowsInserted event problem (RepaintManager deadlock)
-
- Closed
-