我有一个小的图像处理应用程序,可以使用SwingWorker一次做多件事。然而,如果我运行以下代码(过于简化的摘录),它只在JDK7 b70 (windows)上挂起,但在6u16下可以工作。它在另一个worker中启动一个新worker并等待结果(真正的应用程序运行多个子worker并等待所有这一切)。我在这里使用了一些错误的模式(因为在swingworker-pool中有3-5个工人,我想它有10个工人的限制)?
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();
}
});
}
}发布于 2010-05-04 09:12:04
由于还没有人启动这个链接,看起来这实际上是一个已知的bug:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6880336
令人惊讶的是,对于大多数非平凡的应用程序来说,应该是一个令人惊叹的bug的投票不到100票。
发布于 2009-08-27 20:15:59
你的SwingWorkers在你的SwingWorker线程中执行。所以当你看到
似乎挂在sw2.get()上,而jdk7中只有一个swingworker命名的线程。在jdk6上,我一次看到3-5个。- kd304
这是因为SwingWorker类不是一个线程,而是一个在线程上运行的任务,并且Java6中SwingWorker的ExecutorService的默认配置不同于Java7中的配置。例如,您的SwingWorkerExecutorService (在SwingWorker类中定义)为分配给任务的最大线程数有一个不同的值。
//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
发布于 2009-08-27 16:56:49
查看SwingWorker的源代码,它看起来像是将ExecutorService用作工作线程池。在Java6和Java7之间使用的ExecutorService类型可能发生了变化。如果ExecutorService一次只管理一个线程(您似乎已经注意到了),那么您的代码可能会死锁。
这是因为您的'sw2.get()‘调用将阻塞当前线程,而该线程正是sw2将尝试使用的线程。sw2永远不能执行,因为第一个工作线程正在阻塞。
我认为最好的解决方案是改变你的逻辑,这样你就不会像这样调用一连串的Swing工作线程。
https://stackoverflow.com/questions/1342294
复制相似问题