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: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 the thread mechanics.
- Improved performance when executing large numbers of tasks due to reduced per-task invocation overhead.
- A means of bounding the resources, including threads, consumed when executing a collection of tasks.
To use thread pools, you 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, how to handle rejected tasks, and how to create and terminate threads. However, we recommend that you use 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 unbounded thread pool, with automatic thread reclamation. newSingleThreadExecutor
Creates a single background thread. . This task performs some work and then periodically reports what percent of the work it has completed:
WorkerThread
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.println("Worker number: " + workerNumber + ", percent complete: " + i ); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { } } } }, we can specify the number of worker threads to create and the size of the thread pool that will be used to run the threads. This example uses a fixed thread pool so that you can observe the effect of running the program with fewer threads than tasks:
ThreadPoolTest
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 they alternately run to completion and 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,. A
CallableWorkerThread
Callable
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 tasks 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.println("Worker number: " + workerNumber + ", percent complete: " + i ); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { } } return(workerNumber); } }uses the
ThreadPoolTest2
CachedThreadPool
executor service which creates as many threads as needed but reuses previously constructed threads if available. You use the submit method to ask an executor service to run aCallable
. This method returns aFuture
object which gives you control over the task; you can use theFuture
to retrieve the result of running the task, monitor the task, and 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.println("Ending worker: " + futures[i].get()); } catch (Exception e) {} } } }ThreadPoolTest2
. Notice how each worker task is immediately assigned a thread to run in. As each task completes, it returns its identifier, whichThreadPoolTest2
retrieves from the worker task futures:% 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.