Item 68: Prefer executors and tasks to threads

阅读更多

1.  java.util.concurrent contains an Executor Framework, which is a flexible interface-based task execution facility. Creating a work queue requires a single line of code:

 

ExecutorService executor = Executors.newSingleThreadExecutor();

 

 

Here is how to submit a runnable for execution:

 

executor.execute(runnable);

 

 

And here is how to tell the executor to terminate gracefully (if you fail to do this, it is likely that your VM will not exit):

 

executor.shutdown();

 

 

2.  You can wait for a particular task to complete by Future.get method.

 

3.  You can wait for any or all of a collection of tasks to complete using the ExecutorService.invokeAny or ExecutorService.invokeAll methods.

 

4.  You can wait for the executor service’s graceful termination to complete using the ExecutorService.awaitTermination method.

 

5.  You can retrieve the results of tasks one by one as they complete using an ExecutorCompletionService.

 

6.  If you want more than one thread to process requests from the queue, simply call a different static factory that creates a different kind of executor service called a thread pool. If you want something out of the ordinary, you can use the ThreadPoolExecutor class directly. This class lets you control nearly every aspect of a thread pool’s operation.

 

7.  If you’re writing a small program, or a lightly loaded server, using Executors.newCachedThreadPool is generally a good choice, as it demands no configuration and generally “does the right thing.” But a cached thread pool is not a good choice for a heavily loaded production server. In a cached thread pool, submitted tasks are not queued but immediately handed off to a thread for execution. If no threads are available, a new one is created. If a server is so heavily loaded that all of its CPUs are fully utilized, and more tasks arrive, more threads will be created, which will only make matters worse. Therefore, in a heavily loaded production server, you are much better off using Executors.newFixedThreadPool, which gives you a pool with a fixed number of threads, or using the ThreadPoolExecutor class directly, for maximum control.

 

8.  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 accuracy 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.

 

你可能感兴趣的:(Executors,ExecutorService)