书上的例子整理了一下,以作复习之用。
public class ThreadPool extends Object
{
private ObjectFIFO idleWorkers; //空闲线程
private ThreadPoolWorker[] workerList;//所有线程
public ThreadPool(int numberOfThreads){
numberOfThreads = Math.max(1,numberOfThreads);
idleWorkers = new ObjectFIFO(numberOfThreads);
workerList = new ThreadPoolWorker[numberOfThreads];
for(int i=0;i<workerList.length;i++){
//创建并开启线程
workerList[i] = new ThreadPoolWorker(idleWorkers);
}
}
public void execute(Runnable target) throws InterruptedException{
//取得一个空闲线程
ThreadPoolWorker worker = (ThreadPoolWorker)idleWorkers.remove();
worker.process(target);
}
public void stopRequestIdleWorkers(){
try{
Object[] idle = idleWorkers.removeAll();
for(int i=0;i<idle.length;i++){
((ThreadPoolWorker)idle[i]).stopRequest();
}
}catch(InterruptedException x){
Thread.currentThread().interrupt();
}
}
public void stopRequestAllWorkers(){
stopRequestIdleWorkers();
try{
Thread.sleep(250);
}catch(InterruptedException e){}
for(int i=0;i<workerList.length;i++){
if(workerList[i].isAlive()){
workerList[i].stopRequest();
}
}
}
}
public class ThreadPoolWorker extends Object
{
private static int nextWorkerID = 0;
private ObjectFIFO idleWorkers; //空闲线程
private int workerID;
private ObjectFIFO handoffBox; //线程安全的传递Runnable
private Thread internalThread;
private volatile boolean noStopRequested;
public ThreadPoolWorker(ObjectFIFO idleWorkers) {
this.idleWorkers = idleWorkers;
workerID = getNextWorkerID();
handoffBox = new ObjectFIFO(1);
noStopRequested = true;
Runnable r = new Runnable() {
public void run() {
try {
runWork();
} catch ( Exception x ) {
x.printStackTrace();
}
}
};
internalThread = new Thread(r);
internalThread.start();
}
public static synchronized int getNextWorkerID() {
int id = nextWorkerID;
nextWorkerID++;
return id;
}
public void process(Runnable target) throws
InterruptedException {//添加任务
handoffBox.add(target);
}
private void runWork() {
while (noStopRequested){//只要未接到停止请求就不停的处理任务
try {
System.out.println("workerID=" + workerID +
", ready for work");
idleWorkers.add(this);//当前线程加入空闲线程队列
//取得一个任务,执行之
Runnable r = (Runnable)handoffBox.remove();
System.out.println("workerID=" + workerID +
", starting execution of new Runnable: " + r);
runIt(r);
} catch ( InterruptedException x ) {
Thread.currentThread().interrupt();
}
}
}
private void runIt(Runnable r) {
try {
r.run();
} catch (Exception runex) {
System.err.println("Uncaught exception fell through from run()");
runex.printStackTrace();
} finally {
//如果不清除标志,在runWork方法中handoffBox.remove()处
//等待的线程会抛出InterruptedException异常
Thread.interrupted();
}
}
public void stopRequest(){
System.out.println("workerID=" + workerID +
", stopRequest() received.");
noStopRequested = false;
internalThread.interrupt();
}
public boolean isAlive() {
return internalThread.isAlive();
}
}
class ObjectFIFO extends Object
{
private Object[] queue;
private int capacity;
private int size;
private int head;
private int tail;
public ObjectFIFO(int cap){
capacity = (cap>0)?cap:1;
queue = new Object[capacity];
head = 0;
tail = 0;
size = 0;
}
public int getCapacity() {
return capacity;
}
public synchronized int getSize() {
return size;
}
public synchronized boolean isEmpty() {
return ( size == 0 );
}
public synchronized boolean isFull() {
return ( size == capacity );
}
public synchronized void add(Object obj)
throws InterruptedException {
waitWhileFull();
queue[head] = obj;
head = (head + 1)%capacity;
size++;
notifyAll();
}
public synchronized void addEach(Object[] list)
throws InterruptedException {
for ( int i = 0; i < list.length; i++ ) {
add(list[i]);
}
}
public synchronized Object remove()
throws InterruptedException {
waitWhileEmpty();
Object obj = queue[tail];
queue[tail] = null;
tail = ( tail + 1 ) % capacity;
size--;
notifyAll();
return obj;
}
public synchronized Object[] removeAll()
throws InterruptedException {
Object[] list = new Object[size];
for ( int i = 0; i < list.length; i++ ) {
list[i] = remove();
}
return list;
}
public synchronized Object[] removeAtLeastOne()
throws InterruptedException {
waitWhileEmpty();
return removeAll();
}
public synchronized boolean waitUntilEmpty(long msTimeout)
throws InterruptedException {
if (msTimeout == 0L) {
waitUntilEmpty();
return true;
}
long endTime = System.currentTimeMillis()+msTimeout;
long msRemaining = msTimeout;
while(!isEmpty()&&(msRemaining > 0L)) {
wait(msRemaining);
msRemaining = endTime - System.currentTimeMillis();
}
return isEmpty();
}
public synchronized void waitUntilEmpty()
throws InterruptedException {
while (!isEmpty()) {
wait();
}
}
public synchronized void waitWhileEmpty()
throws InterruptedException {
while ( isEmpty() ) {
wait();
}
}
public synchronized void waitUntilFull()
throws InterruptedException {
while ( !isFull() ) {
wait();
}
}
public synchronized void waitWhileFull()
throws InterruptedException {
while ( isFull() ) {
wait();
}
}
}
public class ThreadPoolMain extends Object {
public static Runnable makeRunnable(final String name,
final long firstDelay){
return new Runnable(){
public void run(){
try {
System.out.println(name +": starting up");
Thread.sleep(firstDelay);
System.out.println(name + ": doing some stuff");
Thread.sleep(2000);
System.out.println(name + ": leaving");
}catch(InterruptedException ix) {
System.out.println(name + ": got interrupted!");
return;
}catch(Exception x) {
x.printStackTrace();
}
}
public String toString() {
return name;
}
};
}
public static void main(String[] args){
try {
ThreadPool pool = new ThreadPool(3);
Runnable ra = makeRunnable("RA", 3000);
pool.execute(ra);
Runnable rb = makeRunnable("RB", 1000);
pool.execute(rb);
Runnable rc = makeRunnable("RC", 2000);
pool.execute(rc);
Runnable rd = makeRunnable("RD", 60000);
pool.execute(rd);
Runnable re = makeRunnable("RE", 1000);
pool.execute(re);
pool.stopRequestIdleWorkers();
Thread.sleep(2000);
pool.stopRequestIdleWorkers();
Thread.sleep(5000);
pool.stopRequestAllWorkers();
}catch(InterruptedException ix) {
ix.printStackTrace();
}
}
}
下面将整个流程简要介绍一遍:
idleWorkers是空闲线程阻塞队列,workerList用来存放所有的线程。ThreadPool构造函数中创建指定数量的线程并把他们放到workerList和空闲线程队列里面,当有任务需要执行时调用ThreadPool的execute方法,传递一个Runnable进去,该方法会从空闲线程队列里面取出一个线程(如果没有空闲线程的话就会执行wait操作,这是在ObjectFIFO中实现的)并调用ThreadPoolWorker的process方法,把Runnable任务放进任务队列handoffBox中。handoffBox的容量为1,也就是每次只能存放一个任务。它主要是用来线程安全的传递任务的。当handoffBox为空时,想要执行任务的空闲线程会被阻塞(wait),直到有新的任务添加进来,通知(notify)阻塞的线程。通过ThreadPoolWorker中的runWork()方法可以发现,只要没有停止请求(while (noStopRequested)),会一直重复取空闲线程,获取任务,执行的操作。当需要终止的时候,首先清空空闲线程队列,然后设置noStopRequested为假,调用线程的interrupt方法。