[ Pobierz całość w formacie PDF ]
job.run();
} catch (Exception e) {
// Ignore exceptions thrown from jobs
System.err.println("Job exception: " + e);
}
}
}
}
The actual ThreadPool class shown in Listing 9-2 is rather simple. When the pool is created, we create all the
runnable threads. These are maintained in a LinkedList. We treat the list as a queue, adding at the end and
removing at the beginning. When a new job comes in, we add it to the list. When a thread requests a job, we
get it from the list. Appropriate synchronization is done to block threads while the list is empty:
Listing 9-2: Defining the thread pool.
import java.util.*;
public class ThreadPool {
private LinkedList tasks = new LinkedList();
public ThreadPool(int size) {
for (int i=0; i
121
LinkedList Example
Thread thread = new TaskThread(this);
thread.start();
}
}
public void run(Runnable task) {
synchronized (tasks) {
tasks.addLast(task);
tasks.notify();
}
}
public Runnable getNext() {
Runnable returnVal = null;
synchronized (tasks) {
while (tasks.isEmpty()) {
try {
tasks.wait();
} catch (InterruptedException ex) {
System.err.println("Interrupted");
}
}
returnVal = (Runnable)tasks.removeFirst();
}
return returnVal;
}
The test program is included as part of the pool class. It creates a pool of two threads to do work and five jobs
that just print a message twenty-five times each:
public static void main (String args[]) {
final String message[] = {"Reference List", "Christmas List",
"Wish List", "Priority List", "'A' List"};
ThreadPool pool = new ThreadPool(message.length/2);
for (int i=0, n=message.length; i
final int innerI = i;
Runnable runner = new Runnable() {
public void run() {
for (int j=0; j
System.out.println("j: " + j + ": " + message[innerI]);
}
}
};
pool.run(runner);
}
}
}
When you run the program you'll notice that, at most, two threads are running, and as each task finishes, the
thread grabs another waiting task from the pool. Part of the output follows:
...
j: 20: Reference List
j: 21: Reference List
j: 22: Reference List
j: 23: Reference List
j: 24: Reference List
122
ListIterator
j: 0: Wish List
j: 1: Wish List
j: 2: Wish List
j: 3: Wish List
j: 4: Wish List
j: 5: Wish List
j: 6: Wish List
j: 7: Wish List
j: 0: Priority List
j: 1: Priority List
j: 2: Priority List
...
The main ThreadPool class can be improved in many ways. For instance, you can use lazy initialization to
create the threads in the pool, waiting until they are first needed before taking the creation hit. You can also
add support for priorities to the queue. Right now, jobs are handled in the order in which they come in. A
priority queue implementation is shown in the "Creating Advanced Collections" section of Chapter 16. You
can use that as your data structure instead of the LinkedList to manage tasks.
ListIterator
The ListIterator is an extension to the Iterator. Because lists are ordered and support positional access, you can
use a ListIterator for bidirectional access through the elements of a list. The methods that support this are
found in Table 9-5.
Table 9-5: Summary of the ListIterator Interface
VARIABLE/METHOD VERSION DESCRIPTION
NAME
add() 1.2 Adds an element to the list.
hasNext() 1.2 Checks in the forward direction for more elements in the
iterator.
hasPrevious() 1.2 Checks in the reverse direction for more elements in the
iterator.
next() 1.2 Fetches the next element of the iterator.
nextIndex() 1.2 Returns the index of the next element of the iterator.
previous() 1.2 Fetches the previous element of the iterator.
previousIndex() 1.2 Returns the index of the previous element of the iterator.
remove() 1.2 Removes an element from the iterator.
set() 1.2 Changes the element at a specific position within the list.
While Iterator is very simple to use, there are many different ways to use ListIterator.
" Like an Iterator:
Since ListIterator extends from Iterator, you can use hasNext() and next() to scroll forward through
the list:
123
ListIterator
ListIterator iter = list.listIterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
" In reverse order:
The hasPrevious() and previous() methods function similarly to hasNext() and next(), taking you in
the reverse direction. You just need to start at the end:
[ Pobierz całość w formacie PDF ]