Swingworker实例不同时运行 [英] Swingworker instances not running concurrently
问题描述
我的电脑有4个内核,我正在运行Java swing gui程序。当我运行我的应用程序时,它只使用两个内核和大约30%的CPU利用率。我有大量要处理的文件,并希望将它们分成两个线程,以便使用更多的cpu更快地完成这项任务。
My computer has 4 cores and I am running a Java swing gui program. When I run my application it only uses two cores and about 30% CPU utilization. I have a large number of files to process and want to split them up into two threads to get this task done faster using more cpu.
我有一个名为PrepareTask的SwingWorker类,它有一个带有两个整数的构造函数:
I have a SwingWorker class called PrepareTask, that has a constructor with two ints:
class PrepareTask extends SwingWorker<Void, Void> {
int start, end;
PrepareTask (int start, int end) { ... }
...
public Void doInBackground() {... }
public void done() { ... }
我创建了两个这样的实例:
I create two instances of this like:
PrepareTask prepareTask = new PrepareTask(0,numberOfFiles/2);
prepareTask.execute();
PrepareTask prepareTask2 = new PrepareTask(numberOfFiles/2, numberOfFiles);
prepareTask2.execute();
两者都已启动(显示)但运行时我可以看到(打印stmts)第一个准备必须在第二个开始之前完成(在里面打印stmts)。 CPU利用率与以前相同,约为30%。他们当然都从同一来源获取数据,一个DefaultTableModel。
Both are launched (it appears) but when it runs I can see (print stmts) that the first prepare has to finish (print stmts inside) before the second one starts. And the CPU utilization is the same as before, about 30%. They both of course grab data from the same source, a DefaultTableModel.
关于如何做到这一点或我做错了什么的想法?
谢谢。
Any ideas on how to do this or what I am doing wrong? thanks.
推荐答案
这是SwingWorker从一个Java 6更新到另一个更新的行为的结果。实际上在Java 6的旧SUN bug数据库中有关于它的错误报告。
This is the result of a change in SwingWorker behaviour from one Java 6 update to another. There's actually a bug report about it in the old SUN bug database for Java 6.
SUN将原始的SwingWorker实现从使用N个线程改为使用1个线程有一个无限的队列。因此,您不能再同时运行两个SwingWorkers。 (这也会产生一种可能发生死锁的情况:如果一个swingworker等待另一个等待第一个任务,则一个任务可能会因此导致死锁。)
What happened was SUN changed the original SwingWorker implementation from using N threads, to using 1 thread with an unbounded queue. Therefore you cannot have two SwingWorkers run concurrently anymore. (This also creates a scenario where deadlock may occur: if one swingworker waits for another which waits for the first, one task might enter a deadlock as a result.)
什么你可以做到这一点是使用ExecutorService并发布FutureTasks。这些将提供99%的SwingWorker API(SwingWorker是FutureTask派生物),您所要做的就是正确设置Executor。
What you can do to get around this is use an ExecutorService and post FutureTasks on it. These will provide 99% of the SwingWorker API (SwingWorker is a FutureTask derivative), all you have to do is set up your Executor properly.
这篇关于Swingworker实例不同时运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!