什么时候Event Dispatch Thread开始了?

Pie*_*ter 15 java swing event-dispatch-thread

什么时候开始EDT?什么代码行负责呢?

我的猜测是"someSwingComponent.setVisible(true)"可以解决问题,但我不确定.

谢谢!

cre*_*ama 15

问:EDT何时开始?什么行代码负责[f]呢?

Swing的内部工作原理是JVM特有的.不同的JVM根据不同的标准启动事件调度线程(EDT).一般来说:

EDT在收到第一个时开始AWTEvent.

下面的堆栈跟踪重申了这一点.以下面的main方法为例.

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

在上面的例子中,负责启动EDT的代码行是 frame.setVisible(true);

上述main方法在两个不同的JVM上执行.断点放在EventQueue.initDispatchThread.当断点被击中时,注意到以下堆栈跟踪.

AWT-AppKit线程上使用Mac的JDK :

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 
Run Code Online (Sandbox Code Playgroud)

main线程上使用Oracle的JDK for Windows :

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
Run Code Online (Sandbox Code Playgroud)

在Mac上,拨打电话PostEventQueue.postEvent(AWTEvent).同样在Windows上,进行了一次调用java.awt.EventQueue.postEvent(java.awt.AWTEvent).两人最终打电话EventQueue.initDispatchThread.


作为另一个示例,请考虑以下main方法:

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

main线程上使用Mac的JDK :

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 
Run Code Online (Sandbox Code Playgroud)

main线程上使用Oracle的JDK for Windows :

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
Run Code Online (Sandbox Code Playgroud)

致电SwingUtilties.invokeLater负责启动EDT.这里再次呼吁EventQueue.postEvent(AWTEvent).


关于'我的猜测就是那个'someSwingComponent.setVisible(true)"的想法"诀窍,但我不确定."

不只是任何电话someSwingComponent.setVisible(true)会启动EDT.例如,执行以下main方法不会创建AWT-Event-Queue-0线程:

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

资源

当然,网上有很多关于EDT的资源.