Java – SwingWorker和SwingUtilities.invokeLater()之间的区别

SwingWorker用于以下目的:

  • 用于在不同的线程中运行长时间运行的任务,以防止GUI无响应
  • 用于通过done()方法在任务结束时使用长时间运行的任务生成的结果更新GUI。
  • 用于在不依赖于publish()process()方法的情况下由任务生成和发布的中间结果来不时更新GUI。

SwingUtilities.invokeLater()可以执行上述任务,如下所示:

  • 我们可以执行ExecutorService.submit(new MyRunnable()) ,而不是从EDT执行SwingWorker.execute()方法,因为它还会创建另一个可以执行长时间运行任务的线程。
  • 为了在任务结束时更新GUI,我们可以在任务结束时放置代码(用case1的done()方法编写) SwingUtilites.invokeLater(new RunnableToExecuteDoneMethodCode())
  • 为了在任务中间更新GUI,我们可以将代码(在case1的process()方法中编写) SwingUtilites.invokeLater(new RunnableToExecuteProcessMethodCode())放在我们在case1中调用publish()方法的地方。

我问这个问题是因为Java-SwingWorker中指定的问题- 我们可以从其他SwingWorker调用一个SwingWorker而不是EDT可以通过SwingUtilities.invokeLater()解决但是无法用SwingWorker解决

SwingWorker是一个帮助类 – 它不是你需要使用它,但使用它比手工完成相同的工作要简单得多,也更清晰。 (它还使检查进度更容易。)请注意,它已添加版本6 – 之前有些人使用了Swing Tutorial中定义的更简单的类,或者执行了类似于您注意到的步骤。

1.6+ SwingWorker类的一个重要特性是doInBackground()和done()之间的EDT(Event Dispatch Thread)区别。 您应该将doInBackground()视为doWorkOutsideEDT()和done()作为doWorkInsideEDT()。 运行此教学示例以查看不同的示例。

  System.out.println("TID=" + Thread.currentThread().getId() + " (main)"); final SwingWorker x = new SwingWorker() { @Override protected String doInBackground() throws Exception { final long tid = Thread.currentThread().getId(); System.out.println(""); System.out.println("TID=" + tid + " doInBackground() isEventDispatchThread=" + SwingUtilities.isEventDispatchThread()); System.out.println("Long running code goes here."); return ""; } @Override protected void done() { final long tid = Thread.currentThread().getId(); System.out.println(""); System.out.println("TID=" + tid + " done() isEventDispatchThread=" + SwingUtilities.isEventDispatchThread()); System.out.println("GUI updates/changes go here."); } }; x.execute(); x.get(); 

输出:

 TID=1 (main) TID=9 doInBackground() isEventDispatchThread=false Long running code goes here. TID=16 done() isEventDispatchThread=true GUI updates/changes go here.