Use ThreadPoolExecutor.
Description of ThreadPoolExecutor from API doc:
public class ThreadPoolExecutor extends AbstractExecutorService
An ExecutorService that executes each
submitted task using one of possibly
several pooled threads, normally
configured using Executors factory
methods.
Thread pools address two different
problems: they usually provide
improved performance when executing
large numbers of asynchronous tasks,
due to reduced per-task invocation
overhead, and they provide a means of
bounding and managing the resources,
including threads, consumed when
executing a collection of tasks. Each
ThreadPoolExecutor also maintains some
basic statistics, such as the number
of completed tasks.
Here is simple tutorial for understanding same.
Some more links to understand same:
http://programmingexamples.wikidot.com/threadpoolexecutor