When exactly is the Event Dispatch Thread started?

后端 未结 3 2003
臣服心动
臣服心动 2020-12-17 15:56

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.<

3条回答
  •  忘掉有多难
    2020-12-17 16:26

    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

提交回复
热议问题