模拟线程池代码

书上的例子整理了一下,以作复习之用。

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方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值