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(); } } } }