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