在SwingWorker中运行ExecutorService是一个好习惯吗?

考虑以下代码:

SwingWorker sworker = new SwingWorker() { @Override protected Void doInBackground() throws Exception { ExecutorService executor = Executors.newFixedThreadPool(5); try { for (int j = 0; j < 5; j++) { Callable worker = new MyCallableImpl(); Future future = executor.submit(worker); array[j] = future.get(); } } catch (InterruptedException e) { // some code here } catch (ExecutionException e) { // some code here } // some code here executor.shutdown(); return null; } }; sworker.execute(); 

正如我在标题中所说:在SwingWorker的doInBackground()方法中调用ExecutorService是一个好习惯吗? 它适用于我(JDK1.7),GUI没有被阻止,Executor池中的多个线程在后台运行,但我仍然有些疑惑……

上面的代码对我来说没有多大意义。

如果这里的目标是确保GUI在执行长时间运行的任务时保持响应,那么就不需要使用ExecutorService因为SwingWorker已经提供了该机制。

  • 可以从Executor执行SwingWorkers实例

  • 必须接受Executor不关心SwingWorkers生命周期,反之亦然

  • 必须为SwingWorker实现PropertyChangeListener

  • 在这里说

进一步的回应。 它没有意义,因为你的执行实际上是单线程的。 doInBackground将提交给执行程序并等待该单个任务完成,然后提交另一个任务。

您应该以相同的方式提交,但是将返回的Future存储在某种类型的List中,然后在提交所有任务之后将其中的每一个都存在。

我并没有像doInBackground地提交这些作业。 如果您尝试提交许多任务并且在任何给定时间只提交N,那么您绝对不应该通过SwingWorker.doInBackground执行此操作。 使用ExectorService + SwingUtilities.invokeLater我认为是更好的方法。

只是为了澄清任何混淆,只有当ExecutorService中的任务完成并且需要做的只是更新UI组件时才应使用invokeLater

编辑:用于解决您的评论的示例

 protected Void doInBackground() throws Exception { ExecutorService executor = Executors.newFixedThreadPool(5); List futures = ...; try { for (int j = 0; j < 5; j++) { Callable worker = new MyCallableImpl(); futures.add(executor.submit(new Callable(){ public Object call(){ //expensive time consuming operation final String result = ...;//result from consuming operation SwingUtilities.invokeLater(new Runnable(){ public void run(){ jLabel.setText(result); } }); return new Object(); } )); } for(Future f :futures)f.get(); executor.shutdown(); return null; } 

注意invokeLater是如何进行简单更新的? 这不应该导致您的EDT冻结。