views:

155

answers:

4

I am a building a console Sudoku Solver where the main objective is raw speed.

I now have a ManagerThread that starts WorkerThreads to compute the neibhbors of each cell. So one WorkerThread is started for each cell right now. How can I re-use an existing thread that has completed its work?

The Thread Pool Pattern seems to be the solution, but I don't understand what to do to prevent the thread from dying once its job has been completed.

ps : I do not expect to gain much performance for this particular task, just want to experiment how multi-threading works before applying it to the more complex parts of the code.

Thanks

+12  A: 

Have a look at the Java SE provided java.util.concurrent API. You can create a threadpool using Executors#newFixedThreadPool() and you can submit tasks using the ExecutorService methods. No need to reinvent your own threadpool. Also see the Sun tutorial on the subject.

BalusC
+1 (as usual) ...
T.J. Crowder
@David: Keep in mind that for pure computation tasks, having more threads than there are cores available will slow down, rather than speed up, your code. Obviously that changes if you have a thread blocking on I/O or something.
T.J. Crowder
@T.J. has a fair point. @David, check [`Runtime#availableProcessors()`](http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors%28%29).
BalusC
@BalusC : thanks it looks like what I need.@TJ : really? Creating several threads with a high priority value would not drag more CPU resources away from the other processes already running that have a lower priority?
David
@David: You're welcome. Don't forget to mark the answer accepted (click the green checkmark, also see http://stackoverflow.com/faq). And yes, more threads than the cores available will cause more overhead to manage them which may per saldo be slower after all.
BalusC
@BalusC : i just marked it as accepted... the cookie-session wouldn't let me do it, but it's fixed now! ;-)
David
+3  A: 

when using a thread pool (java.util.concurrent) , you never actually initialized a thread - but rather pass Runnables to the thread pool. you don't need to worry about the thread life-cycle, just do whatever work you need to do in the runnable and let it exit when it's done.

Omry
A: 

Well, if I had to code this logic my self instead of using a package like Quartz from OpenSymphony, I would do the following: I'd have a WorkerThread which extends Thread. This class will also have private property called runnable which is Runnable. This property will hold a reference to the code you'd like to execute. Have a public setter for it. The main thread code will start by running the runnable you initialized it with and then switch to a wait state. Before doing that, it will mark to the pool manager that it has finished and it can be returned to the pool. Next time you need a thread, you pick one from the pool, call setRunnable which sets the property runnable, and then wakes up the thread. It will spawn back to work, enter the infinite loop: execute and runnable and go back to wait state.

Asaf Mesika
+1  A: 

Have a look into using CyclicBarrier synchro: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CyclicBarrier.html

Chris Dennett