在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
注意invokeLater
是如何进行简单更新的? 这不应该导致您的EDT冻结。