Java AWT FileDialog阻塞EDT却不阻碍事件分发的原理探究
关于AWT FileDialog模态阻塞时EDT仍能处理事件的原理疑问
我在使用java.awt.FileDialog时发现,作为模态对话框,调用setVisible(true)会阻塞至用户选择文件或关闭对话框。但setVisible的文档提到:“在事件分发线程(EDT)调用此方法是安全的,因为工具包会确保该方法阻塞时其他事件不会被阻塞”。
为探究原理,我通过ScheduledExecutorService每秒触发EDT事件,实验代码如下:
public class Example { static Thread edt; static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); static void checkThread(String source) { Thread thisThread = Thread.currentThread(); String threadCheck = thisThread == edt ? "same thread" : "different thread"; System.out.println(source + " is running on " + thisThread + " (" + threadCheck + ")"); } public static void main(String[] args) throws Exception { EventQueue.invokeAndWait(() -> edt = Thread.currentThread()); executor.scheduleAtFixedRate(() -> EventQueue.invokeLater(() -> checkThread("Timer")), 1, 1, TimeUnit.SECONDS); EventQueue.invokeLater(() -> { checkThread("File picker"); FileDialog dialog = new FileDialog((Frame) null); dialog.setVisible(true); System.out.println("You picked " + dialog.getFile()); checkThread("File picker"); executor.shutdownNow(); }); } }
实验步骤
- 获取EDT的引用;
- 启动调度器,每秒在EDT执行
checkThread事件,打印线程信息; - 在EDT提交显示FileDialog的事件,前后调用
checkThread。
实验现象与疑问
实验输出显示,所有事件均在同一Thread[AWT-EventQueue-0,6,main]执行,setVisible阻塞期间Timer事件仍正常运行。这与常规线程行为矛盾——常规线程阻塞时无法执行其他代码。
我注意到EventDispatchThread继承自Thread,但它为何能同时处于阻塞与运行状态?难道它并非真实线程?我自己有几个猜测:它由多个真实线程支持、区分不同阻塞类型、存在特殊同步机制,或者存在事件交错风险等。希望能得到原理解析及相关文档参考,解答这种看似矛盾的行为。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

