java - EventQueue 不一致的 ID

标签 java swing concurrency eventqueue

我对以下显示 EventQueue 行为不一致的示例代码有疑问:

public static void main( String[] args ) throws InvocationTargetException, InterruptedException {

    final long[] id1 = new long[ 1 ];
    final long[] id2 = new long[ 1 ];

    EventQueue.invokeAndWait( new Runnable() {
      @Override public void run() {
        id1[ 0 ] = Thread.currentThread().getId();
      }
    } );

    Thread.sleep( 5000 );

    EventQueue.invokeAndWait( new Runnable() {
      @Override public void run() {
        id2[ 0 ] = Thread.currentThread().getId();
      }
    } );

    System.out.println( "id1 = " + id1[0] );
    System.out.println( "id2 = " + id2[0] );

    if(id1[0]!=id2[0]){
      System.out.println("These ID's don't match, even though they were retrieved from the same thread.");
    }

  }

基本上,它获取事件队列线程的 ID,等待 5 秒,然后再次获取 ID。

由于某种原因,ID 不匹配。显然,EventQueue 已被销毁并重新创建。这是正常行为吗?这在某处记录了吗?这是一个错误吗?即使它是不同的实例,它不应该具有相同的 ID 吗?

如果我不执行 Thread.sleep,ID 将匹配。

我的另一个问题是:我该如何解决这个问题?我正在使用一个只能在创建线程上访问的对象。如果这恰好是事件队列(不一定非要如此),我必须能够检查它是否仍然是事件队列。

最佳答案

AWT 事件调度线程可能在不再需要时被关闭(this page 描述了 JDK 7 中实际实现的规范和行为)。

这似乎发生在这里:您使用系统 EventQueue 来处理一个事件。然后就再也不需要它了(没有 AWT/Swing 组件,...)。一段时间后它会关闭。

然后,当您再次使用 EventQueue 时,另一个线程开始接管该角色。

那么这里发生的是您的Runnable.run() 方法do两个不同的线程 上执行。 两个线程都是“AWT 事件调度线程”,只是处于 JVM 生命周期的不同时间。

也许使用 EventQueue.isDispatchThread() 对它进行特殊封装将是一个可能的解决方案。

关于java - EventQueue 不一致的 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7190297/

相关文章:

java - Spring JPA hibernate : slow SELECT query

java - Swing JTable 中 autoCreateRowSorter 的初始状态

c# - 如何跨越多个 TPL 数据流 block 的 MaxDegreeOfParallelism?

java - 由于超时而安全取消线程

java - 读者/作者问题的优先级

java - Jasper 报告生成的 pdf 的下载选项在浏览器中不起作用

java - 如何在java电子邮件中插入for语句

java - JTree - 仅具有固定文件扩展名的文件系统查看器树

java - 设置ContentPane不起作用

java - 如何删除 JPanel 内图像和文本之间的空白?