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

Diy*_*iya 5 java swing multithreading edt

编辑:我已经提到了这个链接,我能够理解 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();
            } 
        }
    });
Run Code Online (Sandbox Code Playgroud)

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

为什么它以这样一种方式实现,即InvocationTargetException在 EDT 线程中调用时会抛出一个?

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

为什么 InvokeLater 允许这样做?

好吧,这是我对 EDT 线程的基本理解:

调用和等待

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

稍后调用

  • 将作业 F 放入 EDT 队列,但不等待其完成。(基本上,发布和返回调用)。
  • 如果我们不关心作业完成,我们可以使用 InvokeLater。
  • 从技术上讲,异步非阻塞调用。

Arp*_*oth 5

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

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

InvokeLate:它有效,因为您没有等待该任务完成。您在完全相同的线程中调用它,但您不会等待它完成,因此这不会导致死锁。