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.
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();
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.
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.
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.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With