Swing app still deadlocking

I was hopeful that this problem would be solved with beta 2 and the fixing of bug 4837639 but now I get this dump.


"Thread-2" prio=5 tid=0x053382d0 nid=0x45c waiting for monitor entry [0x070bf000..0x070bf9e4]
        at sun.awt.AppContext.get(Unknown Source)
        - waiting to lock <0x22f84770> (a java.util.HashMap)
        at javax.swing.SwingUtilities.appContextGet(Unknown Source)
        at javax.swing.RepaintManager.currentManager(Unknown Source)
        at javax.swing.RepaintManager.currentManager(Unknown Source)
        at javax.swing.JComponent.repaint(Unknown Source)
        at java.awt.Component.repaint(Unknown Source)
        at net.java.games.jogl.GLJPanel.display(GLJPanel.java:120)
        at net.java.games.jogl.Animator$1.run(Animator.java:104)
        at java.lang.Thread.run(Unknown Source)

"AWT-EventQueue-0" prio=7 tid=0x053264b8 nid=0x4cc waiting for monitor entry [0x0581f000..0x0581fa64]
        at sun.awt.AppContext.get(Unknown Source)
        - waiting to lock <0x22f84770> (a java.util.HashMap)
        at javax.swing.SwingUtilities.appContextGet(Unknown Source)
        at javax.swing.RepaintManager.currentManager(Unknown Source)
        at javax.swing.RepaintManager.currentManager(Unknown Source)
        at javax.swing.JComponent._paintImmediately(Unknown Source)
        at javax.swing.JComponent.paintImmediately(Unknown Source)
        at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknow
n Source)
        at java.awt.event.InvocationEvent.dispatch(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(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-Windows" daemon prio=7 tid=0x05323788 nid=0x48c runnable [0x0571f000..0x0571fae4]
        at sun.awt.windows.WToolkit.eventLoop(Native Method)
        at sun.awt.windows.WToolkit.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

Here is a little test case that exhibits the same behavior that I am encountering in 1.5.0 beta 2 for windows.


/*
 * Deadlock.java
 *
 * Created on June 7, 2004, 2:55 PM
 */
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;

/**
 *
 * @author  Administrator
 */
public class Deadlock extends JFrame {
  private Object semaphore = new Object();
  private boolean repaintDone = false;
  private BufferedImage image;
  private byte[] bytes;
  private int[] ints;
  private int color = 0;
  
  /** Creates a new instance of Deadlock */
  public Deadlock() {
    setSize( 200, 200 );
    image = new BufferedImage( getSize().width, getSize().height, BufferedImage.TYPE_4BYTE_ABGR );
    DataBuffer b = image.getData().getDataBuffer();
    if( b instanceof DataBufferByte ) {
      System.err.println( "bytes" );
      bytes = ((DataBufferByte)b).getData();
    } else if( b instanceof DataBufferInt) {
      System.err.println( "ints" );
      ints = ((DataBufferInt)b).getData();
    }
  }
  
  public void display() {
    if( !repaintDone ) {
      synchronized( semaphore ) {
        changeImage();
        System.err.println( "Display" );
        repaintDone = true;
      }
    }
    repaint();
  }
  
  public void paintComponent( Graphics g ) {
    synchronized(semaphore) {
      g.drawImage( image, 0, 0, image.getWidth(), image.getHeight(), this );
      System.err.println( "Repaint" );
      repaintDone = true;
    }
  }
  
  private void changeImage() {
    int i = 0;
    int size = 0;
    if( bytes != null ) {
      size = bytes.length;
      for( i = 0; i < size; i++ ) {
        bytes[i] = (byte)color;
      }
      color++;
    } else {
      int temp = 0;
      size = ints.length;
      for( i = 0; i < size; i++ ) {
        temp = 0;
        temp = color;
        temp <<= 8;
        temp |= color;
        temp <<= 8;
        temp |= color;
        temp <<= 8;
        temp |= color;
        ints[i] = temp;
      }
    }
  }
  
  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
    Deadlock d = new Deadlock();
    Animator a = new Animator( d );
    d.addKeyListener( a );
    d.setVisible( true );
    a.start();
  }
  
}

class Animator extends Thread implements KeyListener {
  private Deadlock deadlock;
  private boolean flag = true;
  
  public Animator( Deadlock d ) {
    super();
    deadlock = d;
  }
  
  public void run() {
    while( flag ) {
      deadlock.display();
    }
    deadlock.setVisible( false );
    deadlock.dispose();
    System.exit( 0 );
  }
  
  public void stopApp() {
    flag = false;
  }
  
  public void keyPressed(java.awt.event.KeyEvent keyEvent) {
  }
  
  public void keyReleased(java.awt.event.KeyEvent keyEvent) {
  }
  
  public void keyTyped(java.awt.event.KeyEvent keyEvent) {
    if( keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE ) {
      stopApp();
    }
  }
  
}


I can’t reproduce the hang on beta2 on windows or solaris with this test. Could you please post a complete stack trace? Does the vm detect the deadlock?

This app will deadlock for me but I found it through a bad logic error on my part so bug 4837639 is fixed, thanks, and my app works correctly. If you still want a thread dump I can generate one for you. The thing just prints out ‘display’ and sits there, no stack trace or exception. Could I have flooded the AWTEvent thread with repaint requests and drown the thing? I am running win2k/dual p2 machine.