Sunday, 19 June 2011

FixedThreadPool example

Creates a fixed-size thread pool. Here is the syntax:
public static ExecutorService 
newFixedThreadPool(int nThreads)

Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.

Example
Here is a runnable task called WorkerThread (in a .java source file). The task performs some work and then periodically reports what percent of the work it has completed.
public 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) { }
}
}
}

In FixedThreadPoolDemo (in a .java source file), 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.
import java.util.concurrent.*;
public class FixedThreadPoolDemo {
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();
}
}

Here is the result of running the test with 4 workers and a pool of 2 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: 100

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.

Like most of the other tasks in this chapter, WorkerThread implements the Runnable (in the API reference documentation) interface. Another way to create a task is to implement the Callable (in the API reference documentation) interface, as shown in the following example, CallableWorkerThread (in a .java source file). A Callable is more flexible than a Runnable because it can return a value and throw an exception. To implement a Callable, you provide the call method, which returns a value, in this case, an Integer 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);
}
}

No comments:

Post a Comment