Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6542185

Threading issues with java.awt.EventQueue.push/pop

XMLWordPrintable

    • x86
    • linux

      FULL PRODUCT VERSION :
      java version "1.6.0"
      Java(TM) SE Runtime Environment (build 1.6.0-b105)
      Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Linux gorm 2.6.19.1-mactel.mactel-061225 #1 SMP PREEMPT Mon Dec 25 19:17:52 CET
      2006 i686 GNU/Linux

      or

      Linux novo 2.4.21-37.0.1.ELsmp #1 SMP Wed Jan 11 18:44:17 EST 2006 i686 i686 i386 GNU/Linux

      or

      Linux dio 2.6.9-42.0.3.ELsmp #1 SMP Mon Sep 25 17:28:02 EDT 2006 i686
      i686 i386 GNU/Linux

      or

      Linux io 2.6.11.4-21.11-smp #1 SMP Thu Feb 2 20:54:26 UTC 2006 i686 i686 i386 GNU/Linux

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      It seems that the bug is more likely on multi processor/core machines.

      A DESCRIPTION OF THE PROBLEM :
      Our product currently suffers from a threading issue in conjunction with java.awt.EventQueue.push/pop. We have been able to produce a small example showing the problem (see below). The bug mainly occurs on multi processor/core machines (we are working with Linux). We observed that whenever an own event queue is pushed a new thread is created (see "Before close()" output). After the pop of that own event queue this additional thread should go away which doesn't happen in all cases (see "After close()" output). In cases where more than one AWT-EventQueue thread exists this sometimes leads to a NPE or a deadlock (see examples below). This bug seems to be an incarnation of bug 6424157 (unfortunately the space for comments is to limited to post all the information given in this report).

      NPE:
      Before close()
         Thread[AWT-EventQueue-0,6,main] id = 10
         Thread[AWT-EventQueue-1,6,main] id = 13
      After close()
         Thread[AWT-EventQueue-0,6,main] id = 10
         Thread[AWT-EventQueue-0,6,main] id = 14
      Error: More than one AWT-EventQueue exists.

      Before close()
         Thread[AWT-EventQueue-0,6,main] id = 14
         Thread[AWT-EventQueue-2,6,main] id = 15
      After close()
         Thread[AWT-EventQueue-0,6,main] id = 14
         Thread[AWT-EventQueue-0,6,main] id = 16
      Error: More than one AWT-EventQueue exists.

      Before close()
         Thread[AWT-EventQueue-0,6,main] id = 16
         Thread[AWT-EventQueue-3,6,main] id = 17
      After close()
         Thread[AWT-EventQueue-0,6,main] id = 16
         Thread[AWT-EventQueue-0,6,main] id = 18
         Thread[AWT-EventQueue-3,6,main] id = 19
      Error: More than one AWT-EventQueue exists.

      Exception in thread "AWT-EventQueue-3" java.lang.NullPointerException
              at javax.swing.SwingUtilities.computeIntersection(SwingUtilities.java:473)
              at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:721)
              at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:683)
              at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:663)
              at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:128)
              at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
              at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
              at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
              at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
              at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
              at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
              at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
              at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)



      Deadlock:
      Name: AWT-EventQueue-11
      State: BLOCKED on EventQueueFailure$MyEventQueue@12d8ecd owned by: AWT-EventQueue-7
        Total blocked: 1 Total waited: 0
      Stack trace:
      java.awt.EventQueue.getNextEvent(EventQueue.java:466)
      java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:245)
      java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
      java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
      java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
      java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
      java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

      Name: AWT-EventQueue-7
      State: BLOCKED on java.awt.EventQueue@40ece0 owned by: AWT-XAWT
        Total blocked: 2 Total waited: 44
      Stack trace:
      java.awt.EventQueue.postEventPrivate(EventQueue.java:190)
      java.awt.EventQueue.postEvent(EventQueue.java:175)
      sun.awt.PostEventQueue.flush(SunToolkit.java:1915)
         - locked sun.awt.PostEventQueue@4f7bc2
      sun.awt.SunToolkit.flushPendingEvents(SunToolkit.java:624)
      java.awt.EventQueue.getNextEvent(EventQueue.java:465)
      java.awt.EventQueue.push(EventQueue.java:702)
         - locked EventQueueFailure$MyEventQueue@12d8ecd
         - locked EventQueueFailure$MyEventQueue@11a0d35
      EventQueueFailure$ButtonAction.actionPerformed(EventQueueFailure.java:65)
      javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
      javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
      javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
      javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
      javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
      java.awt.Component.processMouseEvent(Component.java:6038)
      javax.swing.JComponent.processMouseEvent(JComponent.java:3260)
      java.awt.Component.processEvent(Component.java:5803)
      java.awt.Container.processEvent(Container.java:2058)
      java.awt.Component.dispatchEventImpl(Component.java:4410)
      java.awt.Container.dispatchEventImpl(Container.java:2116)
      java.awt.Component.dispatchEvent(Component.java:4240)
      java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
      java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
      java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
      java.awt.Container.dispatchEventImpl(Container.java:2102)
      java.awt.Window.dispatchEventImpl(Window.java:2429)
      java.awt.Component.dispatchEvent(Component.java:4240)
      java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
      java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
      java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
      java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
      java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
      java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
      java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

      Name: AWT-XAWT
      State: BLOCKED on EventQueueFailure$MyEventQueue@11a0d35 owned by: AWT-EventQueue-7
        Total blocked: 2 Total waited: 111
      Stack trace:
      java.awt.EventQueue.wakeup(EventQueue.java:1009)
      java.awt.EventQueue.wakeup(EventQueue.java:1011)
         - locked java.awt.EventQueue@40ece0
      sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      java.lang.reflect.Method.invoke(Method.java:597)
      sun.awt.SunToolkit.wakeupEventQueue(SunToolkit.java:372)
      sun.awt.PostEventQueue.postEvent(SunToolkit.java:1936)
      sun.awt.SunToolkit.postEvent(SunToolkit.java:589)
      sun.awt.X11.XWindow.postEvent(XWindow.java:366)
      sun.awt.X11.XWindow.postEventToEventQueue(XWindow.java:377)
      sun.awt.X11.XWindow.handleMotionNotify(XWindow.java:739)
      sun.awt.X11.XBaseWindow.dispatchEvent(XBaseWindow.java:1100)
      sun.awt.X11.XBaseWindow.dispatchToWindow(XBaseWindow.java:1069)
      sun.awt.X11.XToolkit.dispatchEvent(XToolkit.java:468)
      sun.awt.X11.XToolkit.run(XToolkit.java:626)
      sun.awt.X11.XToolkit.run(XToolkit.java:560)
      java.lang.Thread.run(Thread.java:619)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      In order to reproduce the problem please compile an run the example as follows:

      javac EventQueueFailure.java
      java EventQueueFailure

      When the GUI is shown please press the "Push Me" button.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      No NPE or deadlocks.
      ACTUAL -
      NPE thrown or deadlock.

      REPRODUCIBILITY :
      This bug can be reproduced often.

      ---------- BEGIN SOURCE ----------
      EventQueueFailure.java:

      import java.awt.BorderLayout;
      import java.awt.EventQueue;
      import java.awt.Toolkit;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.util.LinkedList;
      import java.util.List;
      import javax.swing.AbstractAction;
      import javax.swing.Action;
      import javax.swing.JButton;
      import javax.swing.JDialog;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JPanel;
      import javax.swing.JProgressBar;

      public class EventQueueFailure extends JPanel {
      static JButton anotherButton;
          public EventQueueFailure() {
              add(new JButton(new ButtonAction()));
      anotherButton = new JButton("Threads");
      anotherButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
      ButtonAction.printAWTThreads("button action");
      }
      });

      add(anotherButton);
          }
          
          public static void main(String[] args) {
              EventQueue.invokeLater(new Runnable() {
                  public void run() {
                      createAndShowGUI();
                  }
              });
          }
          
          private static void createAndShowGUI() {
              JFrame frame = new JFrame("EventQueueFailure");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              EventQueueFailure panel = new EventQueueFailure();
              frame.getContentPane().add(panel);
              frame.pack();
              frame.setVisible(true);
          }
          
          private static final class ButtonAction extends AbstractAction {
              public ButtonAction() {
                  putValue(Action.NAME, "Push Me");
              }
              
              public void actionPerformed(ActionEvent e) {
      anotherButton.setText("active");
                  SimpleProgressDialog dialog = new SimpleProgressDialog();
                  dialog.pack();
                  dialog.setVisible(true);
                  MyEventQueue myEventQueue = new MyEventQueue();
                  Toolkit.getDefaultToolkit().getSystemEventQueue().push(myEventQueue);
                   for (int i = 0; i < 10; i++) {
                      try {
                          Thread.currentThread().sleep(100);
                      } catch (InterruptedException ex) {
                          ex.printStackTrace();
                      }
                      EventQueue.invokeLater(new ProgressSetter(dialog, i));
                  }
                  printAWTThreads("Before close()");
      anotherButton.setText("waiting");
                  myEventQueue.close();
                  if (printAWTThreads("After close()") > 1) {
                      System.err.println("Error: More than one AWT-EventQueue exists.\n");
                  } else {
                      System.out.println();
                  }
      anotherButton.setText("suspend");
                  dialog.setVisible(false);
              }
              
              private static List<Thread> getAllThreads() {
                  ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
                  while (root.getParent() != null) {
                      root = root.getParent();
                  }
                  Thread[] threads = new Thread[500];
                  int numThreads = root.enumerate(threads, true);
                  List<Thread> list = new LinkedList<Thread>();
                  for (int i = 0; i < numThreads; i++) {
                      list.add(threads[i]);
                  }
                  return list;
              }
              
              private static int printAWTThreads(String msg) {
                  System.out.println(msg);
                  List<Thread> threads = getAllThreads();
                  int numAWTThreads = 0;
                  for (Thread thread : threads) {
                      if (thread.toString().contains("AWT-EventQueue")) {
                          System.out.println(" "+thread.toString()+
                                  " id = "+thread.getId());
                          numAWTThreads++;
                      }
                  }
                  return numAWTThreads;
              }
          }
          
          private static final class MyEventQueue extends EventQueue {
              public MyEventQueue() {
              }
              
              public void close() {
                  super.pop();
              }
          }
          
          private static final class SimpleProgressDialog extends JDialog {
              private JProgressBar progressBar;
              private JLabel progressLabel;
              public SimpleProgressDialog() {
                  progressBar = new JProgressBar();
                  progressBar.setMinimum(0);
                  progressBar.setMaximum(10);
                  progressLabel = new JLabel("Performing work ...");
                  JPanel panel = new JPanel(new BorderLayout());
                  panel.add(progressBar, BorderLayout.CENTER);
                  panel.add(progressLabel, BorderLayout.SOUTH);
                  getContentPane().add(panel);
              }
              
              public void setProgress(int progress) {
                  progressBar.setValue(progress);
              }
          }
          
          private static final class ProgressSetter implements Runnable {
              private SimpleProgressDialog dialog;
              private int progress;
              
              public ProgressSetter(SimpleProgressDialog dialog, int progress) {
                  this.dialog = dialog;
                  this.progress = progress;
              }
              
              public void run() {
                  dialog.setProgress(progress);
              }
          }
      }
      ---------- END SOURCE ----------

            son Oleg Sukhodolsky (Inactive)
            ryeung Roger Yeung (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: