Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
A thread pool is a managed collection of threads that are available to perform tasks. Thread pools usually provide the following:In addition, thread pools relieve you from having to manage the life cycle of threads. They allow to take advantage of threading, but focus on the tasks that you want the threads to perform instead of thread mechanics.
- Improved performance when executing large numbers of tasks as a result of reduced per-task invocation overhead.
- A way of bounding the resources, including threads, consumed when executing a collection of tasks.
To use thread pools, instantiate an implementation of the
ExecutorService
interface and hand it a set of tasks. The choices of configurable thread pool implementations areThreadPoolExecutor
andScheduledThreadPoolExecutor
. These implementations allow you to set the core and maximum pool size, the type of data structure used to hold the tasks, the way to handle rejected tasks, and the way to create and terminate threads. However, we recommend using the more convenient factory methods of theExecutors
class listed in the following table. These methods preconfigure settings for the most common usage scenarios.Here is a runnable task called
Factory Methods in the Executors Class Method Description newFixedThreadPool(int)
Creates a fixed-size thread pool. newCachedThreadPool
Creates an unbounded thread pool with automatic thread reclamation. newSingleThreadExecutor
Creates a single background thread. WorkerThread
. The task performs some work and then periodically reports what percent of the work it has completed.Inpublic class WorkerThread implements Runnable { private int workerNumber; WorkerThread(int number) { workerNumber = number; } public void run() { for (int i=0;i<=100;i+=20) { //Perform some work... System.out.format("Worker number: %d, percent complete: %d%n", workerNumber, i); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { } } } }ThreadPoolTest
, you can specify the number of worker threads to create and the size of the thread pool that will be used to run the threads. The following example uses a fixed thread pool so that you can observe the effect of running the program with fewer threads than tasks.Here is the result of running the test with 4 workers and a pool of 2 threads.import java.util.concurrent.*; public class ThreadPoolTest { public static void main(String[] args) { int numWorkers = Integer.parseInt(args[0]); int threadPoolSize = Integer.parseInt(args[1]); ExecutorService tpes = Executors.newFixedThreadPool(threadPoolSize); WorkerThread[] workers = new WorkerThread[numWorkers]; for (int i = 0; i < numWorkers; i++) { workers[i] = new WorkerThread(i); tpes.execute(workers[i]); } tpes.shutdown(); } }Notice how workers 0 and 1 are assigned to the two threads in the pool and that they alternately run to completion, then tasks 2 and 3 are assigned to the threads.% java ThreadPoolTest 4 2 Worker number: 0, percent complete: 0 Worker number: 1, percent complete: 0 Worker number: 0, percent complete: 20 Worker number: 0, percent complete: 40 Worker number: 1, percent complete: 20 Worker number: 0, percent complete: 60 Worker number: 0, percent complete: 80 Worker number: 0, percent complete: 100 Worker number: 1, percent complete: 40 Worker number: 1, percent complete: 60 Worker number: 2, percent complete: 0 Worker number: 1, percent complete: 80 Worker number: 2, percent complete: 20 Worker number: 2, percent complete: 40 Worker number: 1, percent complete: 100 Worker number: 2, percent complete: 60 Worker number: 2, percent complete: 80 Worker number: 2, percent complete: 100 Worker number: 3, percent complete: 0 Worker number: 3, percent complete: 20 Worker number: 3, percent complete: 40 Worker number: 3, percent complete: 60 Worker number: 3, percent complete: 80 Worker number: 3, percent complete: 100Like most of the other tasks in this chapter,
WorkerThread
implements theRunnable
interface. Another way to create a task is to implement theCallable
interface, as shown in the following example,CallableWorkerThread
. ACallable
is more flexible than aRunnable
because it can return a value and throw an exception. To implement aCallable
, you provide thecall
method, which returns a value, in this case, anInteger
that represents the task's number.import java.util.concurrent.*; public class CallableWorkerThread implements Callable<Integer> { private int workerNumber; CallableWorkerThread(int number) { workerNumber = number; } public Integer call() { for (int i = 0; i <= 100; i += 20) { //Perform some work... System.out.format("Worker number: %d, percent complete: %d%n", workerNumber, i); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) {} } return(workerNumber); } }ThreadPoolTest2
uses theCachedThreadPool
executor service, which creates as many threads as needed but reuses previously constructed threads if available. You use thesubmit
method to ask an executor service to run aCallable
. This method returns aFuture
object, which gives you control over the task; you can useFuture
to retrieve the result of running the task, to monitor the task, and to cancel the task. For example, to gain access to the return result, simply call the methodget
.Here's the result of runningpublic class ThreadPoolTest2 { public static void main(String[] args) { int numWorkers = Integer.parseInt(args[0]); ExecutorService tpes = Executors.newCachedThreadPool(); CallableWorkerThread workers[] = new CallableWorkerThread[numWorkers]; Future<Integer> futures[] = new Future[numWorkers]; for (int i = 0; i < numWorkers; i++) { workers[i] = new CallableWorkerThread(i); futures[i]=tpes.submit(workers[i]); } for (int i = 0; i < numWorkers; i++) { try { System.out.format("Ending worker: %d%n", futures[i].get()); } catch (Exception e) {} } } }ThreadPoolTest2
. Notice how each worker's task is immediately assigned a thread to run in. As each task completes, it returns its identifier, whichThreadPoolTest2
retrieves from the worker taskfutures
.% java ThreadPoolTest2 4 Worker number: 0, percent complete: 0 Worker number: 1, percent complete: 0 Worker number: 2, percent complete: 0 Worker number: 3, percent complete: 0 Worker number: 3, percent complete: 20 Worker number: 3, percent complete: 40 Worker number: 3, percent complete: 60 Worker number: 1, percent complete: 20 Worker number: 0, percent complete: 20 Worker number: 1, percent complete: 40 Worker number: 2, percent complete: 20 Worker number: 3, percent complete: 80 Worker number: 0, percent complete: 40 Worker number: 2, percent complete: 40 Worker number: 2, percent complete: 60 Worker number: 1, percent complete: 60 Worker number: 3, percent complete: 100 Worker number: 2, percent complete: 80 Worker number: 2, percent complete: 100 Worker number: 0, percent complete: 60 Worker number: 0, percent complete: 80 Worker number: 0, percent complete: 100 Worker number: 1, percent complete: 80 Ending worker: 0 Worker number: 1, percent complete: 100 Ending worker: 1 Ending worker: 2 Ending worker: 3
Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.