When exactly is the Event Dispatch Thread started?

event-dispatch-thread, java, swing

Solution

Q: When exactly is the EDT started? What line of code is responsible [f]of it?

The inner workings of Swing are JVM-specific. Different JVMs start the Event Dispatch Thread (EDT) based on differing criteria. In general though:

The EDT starts when it receives its first `AWTEvent`.

The stack traces below reaffirm this point. Take for example the following `main` method.

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setVisible(true);
}

In the example above, the line of code responsible for starting the EDT is `frame.setVisible(true);`

The above `main` method was executed on two different JVMs. A breakpoint was placed at `EventQueue.initDispatchThread`. When the breakpoint was hit, the following stack traces were noted.

Using the Mac's JDK on the `AWT-AppKit` thread:

EventQueue.initDispatchThread() line: 906   
EventQueue.wakeup(boolean) line: 1109   
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39  
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25  
Method.invoke(Object, Object...) line: 597  
SunToolkit.wakeupEventQueue(EventQueue, boolean) line: 348  
PostEventQueue.postEvent(AWTEvent) line: 2137   
SunToolkit.postEvent(AppContext, AWTEvent) line: 583    
SunToolkit.executeOnEventHandlerThread(PeerEvent) line: 654 
SunToolkit.executeOnEventHandlerThread(Object, Runnable) line: 631  
EventFactoryProxy.windowMoved(CWindow) line: 89 

Using Oracle's JDK for Windows on the `main` thread:

java.awt.EventQueue.initDispatchThread() line: 861  
java.awt.EventQueue.postEventPrivate(java.awt.AWTEvent) line: 199   
java.awt.EventQueue.postEvent(java.awt.AWTEvent) line: 180  
javax.swing.RepaintManager.scheduleProcessingRunnable(sun.awt.AppContext) line: 1369    
javax.swing.RepaintManager.nativeAddDirtyRegion(sun.awt.AppContext, java.awt.Container, int, int, int, int) line: 548   
javax.swing.SwingPaintEventDispatcher.createPaintEvent(java.awt.Component, int, int, int, int) line: 45 
sun.awt.windows.WFramePeer(sun.awt.windows.WComponentPeer).postPaintIfNecessary(int, int, int, int) line: 741   
sun.awt.windows.WFramePeer(sun.awt.windows.WComponentPeer).handlePaint(int, int, int, int) line: 736    
sun.java2d.d3d.D3DScreenUpdateManager.repaintPeerTarget(sun.awt.windows.WComponentPeer) line: 274   
sun.java2d.d3d.D3DScreenUpdateManager.createScreenSurface(sun.awt.Win32GraphicsConfig, sun.awt.windows.WComponentPeer, int, boolean) line: 175  
...
sun.awt.windows.WToolkit.createFrame(java.awt.Frame) line: 383  
javax.swing.JFrame(java.awt.Frame).addNotify() line: 460    
javax.swing.JFrame(java.awt.Window).show() line: 859    
javax.swing.JFrame(java.awt.Component).show(boolean) line: 1584 
javax.swing.JFrame(java.awt.Component).setVisible(boolean) line: 1536   
javax.swing.JFrame(java.awt.Window).setVisible(boolean) line: 842   
Example.main(java.lang.String[]) line: 113

On the Mac, a call to `PostEventQueue.postEvent(AWTEvent)` is made. Similarly on Windows, a call to `java.awt.EventQueue.postEvent(java.awt.AWTEvent)` is made. Both eventually call `EventQueue.initDispatchThread`.

As another example, consider the following `main` method:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            System.out.println("Start!");
        }
    });
}

Using the Mac's JDK on the `main` thread:

EventQueue.initDispatchThread() line: 906 [local variables unavailable] 
EventQueue.postEventPrivate(AWTEvent) line: 227 
EventQueue.postEvent(AWTEvent) line: 208    
EventQueue.invokeLater(Runnable) line: 1048 
SwingUtilities.invokeLater(Runnable) line: 1267 
Example.main(String[]) line: 31 

Using Oracle's JDK for Windows on the `main` thread:

java.awt.EventQueue.initDispatchThread() line: 861  
java.awt.EventQueue.postEventPrivate(java.awt.AWTEvent) line: 199   
java.awt.EventQueue.postEvent(java.awt.AWTEvent) line: 180  
java.awt.EventQueue.invokeLater(java.lang.Runnable) line: 999   
javax.swing.SwingUtilities.invokeLater(java.lang.Runnable) line: 1267

The call to `SwingUtilties.invokeLater` is responsible for starting the EDT. Here again, calls to `EventQueue.postEvent(AWTEvent)` are made.

Thoughts on 'My guess is that "someSwingComponent.setVisible(true)" does the trick, but I'm not sure.'

Not just any call to `someSwingComponent.setVisible(true)` will start the EDT. For example, executing the following `main` method does not create the `AWT-Event-Queue-0` thread:

public static void main(String[] args) {
    JLabel label = new JLabel();
    label.setVisible(true);
}

Resources

Of course, there are many resources online about the EDT.

- "The Event Dispatch Thread" from The Java Tutorials's "Lesson: Concurrency in Swing"

- "Threads and Swing" from the Sun Developer Network

- "Swing Threads" from the Java Glossary at mindprod.com

- "How does the event dispatch thread work?" on Stack Overflow

Problem

When exactly is the EDT started? What line of code is responsible of it? My guess is that "someSwingComponent.setVisible(true)" does the trick, but I'm not sure. Thanks!

Original source

Related problems