为什么要在EDT线程外调用SwingUtils.invokeAndWait()方法?

时间:2016-07-11 11:15:44

标签: java multithreading swing edt

修改:我已经提到了这个link,我能够理解InvokeLater的代码流。我的问题是,为什么这种逻辑以这种方式实现?有什么具体原因吗?

以下是我的代码:

  private void init() 
    {
    JFrame jfr = new JFrame();
    jfr.setSize(500, 500);
    jfr.setVisible(true);
    jfr.setTitle("Test");


    JButton jb = new JButton("Ok");
    jfr.add(jb);

    jb.addActionListener(new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            try 
            {
                SwingUtilities.invokeAndWait(new Runnable() 
                {
                    @Override
                    public void run() 
                    {
                        System.out.println("hello");
                    }
                });
            } 
            catch (Exception e1) 
            {
                e1.printStackTrace();
            } 
        }
    });

第一个问题(使用InvokeAndWait时):

为什么它以在EDT线程中调用时抛出InvocationTargetException的方式实现?

第二个问题(使用InvokeLater时):

为什么InvokeLater允许这个?

嗯,这是我对EDT主题的基本理解:

InvokeAndWait

  • 将作业F放入EDT事件队列并等待直到EDT 执行它。
  • 此调用将阻止,直到所有挂起的AWT事件(A,B,C,D,E)都有 已处理并(然后)执行F后控制 回报。
  • 当且仅当提交的作业完成时才返回。(控制 F完成后返回。)
  • 从技术上讲,是一种同步阻止呼叫。

的invokeLater

  • 将作业F放入EDT队列,但不等待它 完成。(基本上是发布和回电)。
  • 如果我们不关心工作完成情况,我们可以使用InvokeLater。
  • 从技术上讲,是一种异步非阻塞呼叫。

1 个答案:

答案 0 :(得分:4)

EDT与AWT相同。 AWT中的所有UI事件都安排在名为EDT的单个线程上。基本上是用于在Swing中处理UI相关事件的线程。

InvokeAndWait:基本上,您在同一个线程上调用任务,然后等待该任务完成。这会导致死锁。您的方法永远不会返回,因为您正在等待任务,任务将永远不会运行,因为您的方法永远不会完成。

InvokeLate:它的工作原理是因为您没有等待完成该任务。你在完全相同的线程中调用它,但你没有等待它完成,所以这不会导致死锁。