8

I'm in the process of designing a Java GUI driven application that runs a number of separate tasks, each within its own SwingWorker extended class. This is the normal design I use in order to run tasks on their own threads and still keep the EDT free to update the GUI. Each SwingWorker is started on its own thread using an Executors.newCachedThreadPool.

However, within one particular class, there is a task that requires quite a long time to process. The task contains a for loop that performs some calculations up to six times.

I've had the thought of implementing each of the six calculations within their own thread to speed up processing time, but I'm not sure of the best way of implementing this.

Is it possible to both extend SwingWorker and implement Runnable, and then use a void Run() method within the for loop, starting a new Thread each time, or using a cachedThreadPool.

Or am I better off just using standard Thread() implementation?

Any advice or suggestions would be appreciated.

Thanks in advance

Josh

4
  • 8
    "I've had the thought of implementing each of the six calculations within their own thread to speed up processing time" [sic]... This kind of parallel computation to speed up a CPU-bound app shall only bring a speedup if the CPU you're running your app on has at least 6 cores available to your Java app. If you've got only, say, two cores, then spawning 6 threads instead of two shall actually slow your program down... Commented Feb 10, 2012 at 1:17
  • Ahh yes, that makes perfect sense!! Thank you. Commented Feb 10, 2012 at 8:20
  • @user988052 that doesn't make any sense. If you have x threads, then you don't necessarily need at least x cores to make the program run faster. As long as there is more than 1 logical CPU available to the JVM, the OS will try to spread those threads among those logical CPUs. More logical CPUs -->> fewer threads per CPU -->> finishes faster. It can be a lot more complicated than that (when a few locks are involved, for example), I know, but it usually works this way. Commented Feb 10, 2012 at 9:39
  • @SoboLAN: it does make a lot of sense: if you are CPU-bound you cannot magically make more CPU cycles available to your app by spawning more threads! It won't work. Quite some people upvoted my comment btw ; ) Commented Feb 10, 2012 at 11:30

1 Answer 1

8

user988052 is right of course - if you don't have a multi core CPU, doing the computation in six different threads will actually slow down your application because of the overhead that comes with the creation and administration of threads.

If you want to do this calculations in six separate threads nevertheless, you could use a SwingWorker as the managing thread and spawn off 5-6 new threads within it. Using ExecutorService would then be the way to go, since it uses a pool of threads and thus minimizes the overhead that comes with the creation and disposal of a thread.

Edit: to answer your comment:

I think the best way would be the implement your calculation in a Runnable (so that each of the six calculations can run separately), then simply use an ExecutorService, instantiate your Runnablesix times and use ExecutorService.submit(Runnable task). You can do all of this within the SwingWorker.doInBackground() method.

You should never call the run() method yourself - let that be done by a Thread/ExecutorService.

Sign up to request clarification or add additional context in comments.

5 Comments

So would I need to create a run method within the swingworker class, and then call run each time I wanted a new thread to execute using the Executor?
I think it depends a lot on how long you expect the calculations to take. If we're talking about a compute time of about 2 seconds, then it's probably not a great idea to use the 6 threads. But if it's more than that (10s, 30s, 1min, 5min etc.), then the 6 threads do make sense. All the overhead generated by creating/administrating/switching between the 6 threads is computationally SOOOOOO cheap these days, that it shouldn't be an issue. If you think it makes more sense to create the 6 threads, do it. It might even speed things up if the user has a dual-core/triple-core/quad-core/etc. CPU.
@SoboLAN: That's why I said "If you want to do this calculations in six separate threads nevertheless". If creating six threads will e.g., improve readability/maintainability of the code, go for it. Otherwise it's just additional overhead (even if a small one) that does not bring any benefits.
Thanks Mort, I think that's just what I needed to read. With regards to the tasks, five of the runs within the loop take anywhere from 1-20 seconds. The sixth however could take up to three hours to complete, and it might be the one that starts first. I just wanted to let that task get on with it without holding the other, much shorter ones up. Thanks for all the comments!!!
Great answer, does the parent swing worker need to wait for all tasks within the executor service to complete? In other words, if the swing worker spawns these 6 subtasks and finishes executing via the done method will the subtasks continue working or will they be cleaned up along with the original swing worker thread?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.