EDT,异步,同步

时间:2015-11-13 20:02:30

标签: java multithreading asynchronous synchronous event-dispatch-thread

从EDT(事件调度程序线程)启动新线程时,新线程将永远不会是EDT,因为只有一个EDT,对吧?我问我看到一些代码检查if (!SwingUtils.isDispatcherThread()),我想知道为什么需要这个检查?

我的问题是:在启动新线程时,是什么使它同步(必须等待新线程完成)或异步(新线程立即返回)?相应如何自己启动同步或异步线程?

使用以下作为示例。在EDT中启动非EDT线程时,如下所示:

public void actionPerformed(final ActionEvent e)
{
    final Runnable runnable = new Runnable()
    {
      @Override
      public void run()
      {
        //do some non-gui task. The task is not long-running, but 
        //could be blocked
        doTask();       
      }
    }; 

    new Thread(runnable).start();
  }
});

EDT产生的非EDT线程是同步还是异步?如果doTask()挂起,是否应阻止EDT UI?

如果我无法控制doTask()并且该方法无法更改,那么处理生成新线程并且新线程可能挂起的情况的好方法是什么?在父线程中使用Thread.join()

2 个答案:

答案 0 :(得分:2)

  

新线程永远不会是EDT,因为只有一个EDT,对吗?

右。

  

我问我看到一些代码检查" if(!SwingUtils.isDispatcherThread())",我想知道为什么需要这个检查?

因为有时候,可以从EDT或后台线程调用方法,并且必须根据当前线程采取不同的行为。

  

启动新线程时,是什么使它同步(必须等待新线程完成)或异步(新线程立即返回)?

当你开始一个新线程时,新线程总是同时运行到产生线程。除非您明确地加入(或使用其他同步机制),否则产生线程永远不会等待生成的线程完成。

  

如果doTask()挂起,EDT UI是否会被阻止?

不,除非例如生成的线程在保持EDT尝试获取的锁定时挂起。

  

如果我无法控制doTask()并且该方法无法更改,那么处理生成新线程并且新线程可能挂起的情况的好方法是什么?在父线程中使用Thread.join()?

情况会更糟:现在EDT也会挂起,从而完全冻结UI,直到挂起的线程停止挂起并终止。

如果你有一个悬挂线程,那么修复它正在执行的代码,这样它就不会再挂起了。如果您无法解决问题,请让负责该代码的人员进行修复。

答案 1 :(得分:0)

  1. 美国东部时间:是的,只有1个EDT。你做的任何线程都不是EDT
  2. 同步与异步:java中的Thread是一个类似于任何其他的类,但是当你调用start()时,它会创建一个新的线程来运行run()方法或Runnable中的任何内容.run方法,如果异步提供Runnable。
  3. 方法可能会阻止/永不返回:关键是使用回调/侦听器...在处理过程中的某个时刻调用的方法会导致更新。停止被阻塞的线程没有通用的解决方案,但是在许多情况下可以工作的2种机制是(a)InputStream / Reader.close(),如果你在输入流或读取器上等待数据,或者(b)线程。中断