首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JDK-7 SwingWorker死锁?

JDK-7 SwingWorker死锁?
EN

Stack Overflow用户
提问于 2009-08-27 16:42:51
回答 4查看 2.7K关注 0票数 4

我有一个小的图像处理应用程序,可以使用SwingWorker一次做多件事。然而,如果我运行以下代码(过于简化的摘录),它只在JDK7 b70 (windows)上挂起,但在6u16下可以工作。它在另一个worker中启动一个新worker并等待结果(真正的应用程序运行多个子worker并等待所有这一切)。我在这里使用了一些错误的模式(因为在swingworker-pool中有3-5个工人,我想它有10个工人的限制)?

代码语言:javascript
复制
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Swing {
       static SwingWorker<String, Void> getWorker2() {
               return new SwingWorker<String, Void>() {
                       @Override
                       protected String doInBackground() throws Exception {
                               return "Hello World";
                       }
               };
       }
       static void runWorker() {
               SwingWorker<String, Void> worker 
                   = new SwingWorker<String, Void>() {
                       @Override
                       protected String doInBackground() throws Exception {
                               SwingWorker<String, Void> sw2 = getWorker2();
                               sw2.execute();
                               return sw2.get();
                       }
               };
               worker.execute();
               try {
                       System.out.println(worker.get());
               } catch (Exception e) {
                       e.printStackTrace();
               }
       }
       public static void main(String[] args) {
               SwingUtilities.invokeLater(new Runnable() {
                       @Override
                       public void run() {
                               runWorker();
                       }
               });
       }

}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-05-04 09:12:04

由于还没有人启动这个链接,看起来这实际上是一个已知的bug:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6880336

令人惊讶的是,对于大多数非平凡的应用程序来说,应该是一个令人惊叹的bug的投票不到100票。

票数 6
EN

Stack Overflow用户

发布于 2009-08-27 20:15:59

你的SwingWorkers在你的SwingWorker线程中执行。所以当你看到

似乎挂在sw2.get()上,而jdk7中只有一个swingworker命名的线程。在jdk6上,我一次看到3-5个。- kd304

这是因为SwingWorker类不是一个线程,而是一个在线程上运行的任务,并且Java6中SwingWorker的ExecutorService的默认配置不同于Java7中的配置。例如,您的SwingWorkerExecutorService (在SwingWorker类中定义)为分配给任务的最大线程数有一个不同的值。

代码语言:javascript
复制
//From Java 6 SwingWorker

private static final int MAX_WORKER_THREADS = 10;

public final void execute() {
    getWorkersExecutorService().execute(this);
}

private static synchronized ExecutorService getWorkersExecutorService() {
...
private static synchronized ExecutorService getWorkersExecutorService() {
new ThreadPoolExecutor(0, MAX_WORKER_THREADS,
                                     1L, TimeUnit.SECONDS,
                                     new LinkedBlockingQueue<Runnable>(),
                                     threadFactory)
}

您只有一个线程在运行SwingWorker任务,并且第一个任务正在等待第二个任务的完成,而第二个任务无法运行,因为第二个任务将在其上运行的线程正在等待第二个任务完成,然后它才会返回。使swingworker线程依赖于另一个线程的执行肯定会导致死锁。您可能希望考虑使用ExecutorService来调度要在SwingWorker线程上运行的事件,并且不要使一个调度事件依赖于另一个调度事件的完成。

Java 7 SwingWorker

票数 1
EN

Stack Overflow用户

发布于 2009-08-27 16:56:49

查看SwingWorker的源代码,它看起来像是将ExecutorService用作工作线程池。在Java6和Java7之间使用的ExecutorService类型可能发生了变化。如果ExecutorService一次只管理一个线程(您似乎已经注意到了),那么您的代码可能会死锁。

这是因为您的'sw2.get()‘调用将阻塞当前线程,而该线程正是sw2将尝试使用的线程。sw2永远不能执行,因为第一个工作线程正在阻塞。

我认为最好的解决方案是改变你的逻辑,这样你就不会像这样调用一连串的Swing工作线程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1342294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档