Thread pools and work queues

http://www.ibm.com/developerworks/library/j-jtp0730/index.html

线程池的原理:

1. 内部维护若干个线程,这些线程一直保持运行/阻塞状态;

2. 维护一个队列,通过锁的方式让这些线程从队列中取任务;

3. 如果队列没有任务,则阻塞当前请求任务的线程;

4. 当有新的任务加入到任务队列时,唤醒与锁绑定的等待集中的线程

这就是线程池最基本的原理!

package thread;

import java.util.LinkedList;

public class WorkQueue {
	
	private final int nThreads;
	private final PoolWorker[] threads;
	private final LinkedList queue;
	
	public WorkQueue(int nThreads) {
		this.nThreads = nThreads;
		threads = new PoolWorker[nThreads];
		queue = new LinkedList();
		
		for(int i=0; i<nThreads; i++) {
			threads[i] = new PoolWorker("worker-" + i);
			threads[i].start();
			System.out.println(threads[i].getName()+" starts to work");
		}
	}
	
	//面向接口进行设计,只要是实现Runnable接口的任务都可以被接收
	public void execute(Runnable task) {
		synchronized(queue) {
			queue.add(task);
			System.out.println("$$$ current tasks:" + queue.size());
			queue.notify();
		}
	}
	
	//worker的任务:处理任务队列 Task Queue 中的任务
	private class PoolWorker extends Thread {
		
		public PoolWorker(String threadName) {
			super(threadName);
		}
		
		public void run() {
			Runnable task;
			for(;;) {
				synchronized (queue) {
					while(queue.isEmpty()) {
						try {
							System.out.println("there is no task! "+Thread.currentThread().getName() + " is waiting...");
							queue.wait();
						} catch (InterruptedException ignored) {}
					}
					//取出任务
					task = (Runnable)queue.removeFirst();
				}
				try{
					task.run();
				} catch(RuntimeException e) {
					//log something here
				}
			}
		}
	}
}
package thread;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * 实现Runnable表示此类为任务类
 *
 */
public class FileSaver implements Runnable {
	
	private File file;
	
	public FileSaver(File file) {
		this.file = file;
	}

	@Override
	public void run() {
		try {
			long mills = new Random().nextInt(10000);
			Thread.sleep(mills);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
			System.out.println(Thread.currentThread().getName() + ": Write file to disk at " + sdf.format(new Date()) + "--->" + file.getName() + ", takes " + mills + " ms");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}
package thread;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Random;

public class Client {
	public static void main(String[] args) {
		//系统启动便初始化工作队列
		WorkQueue queue = new WorkQueue(2);
		
		//模拟客户端请求
		Random rand = new Random();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		int i = 1;
		while(true) {
			try {
				Thread.sleep(rand.nextInt(5000));
				String fileName = "file"+(i++);
				System.out.println("One request arrive at " + sdf.format(Calendar.getInstance().getTime()) + ", fileName=" + fileName);
				File file = new File(fileName);
				FileSaver saver = new FileSaver(file);
				queue.execute(saver);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

猜你喜欢

转载自just2learn.iteye.com/blog/2069450