Ref: Effective Java by Joshua Bloch
In release 1.5, java.util.concurrent was added to the Java platform. This package contains an Executor Framework, which is a flexible interface-based task execution facility. Creatin a work queue and submitting a task is as easy as
Choosing the executor service for a particular application can be tricky. Executors.newCachedThreadPool is generally good choise if you writing a small lightly loaded program, letting ExecutorService "does the right thing". But it is not a good choice for heavily loaded production servers, because this type of executor service creates a new thread whenever it does not find an idle one. So more task arrive, more threads will be created, which will only make matters worse. Therefore, in a heavily loaded production server, it is much better off using Executors.newFixedThreadPool.
There are two kinds of tasks: Runnable and its close cousing Callable (which is like Runnable except it returns a value).
The Executor Framework also has a replacement for java.util.Timer, which is ScheduledThreadPoolExecutor. While it is easier to use a timer, a scheduled thread pool executor is much more flexible. A timer uses only a single thread for task execution, which can hurt timing acuracy in the presence of long running tasks. If a timer's sole thread throws an uncaught exception, the timer ceases to operate. A scheduled thread pool executor supports multiple threads and recovers gracefully from tasks that throw unchecked exceptions.