线程池也许很多比较陌生 但是提到servlet每个人都知道,servlet就是用线程池来处理请求的
一个线程池由线程池管理器 工作线程 任务队列和任务接口组成
[b]一 线程池管理器[/b]---ThreadPoolMananger 主要负责启动 停止工作线程
[code]public class ThreadPoolManager {
private static int DEFAULT_POOL_SIZE = 4;
private List<WorkThread> threadPool;
private Queue<Task> taskQueue;
private int poolSize;
public ThreadPoolManager(){
this(DEFAULT_POOL_SIZE);
}
public ThreadPoolManager(int poolSize){
if(poolSize <= 0){
this.poolSize = DEFAULT_POOL_SIZE;
}else{
this.poolSize = poolSize;
}
threadPool = new ArrayList<WorkThread>(this.poolSize);
taskQueue = new ConcurrentLinkedQueue<Task>();
startup();
}
/**
* 启动线程池 开始处理任务
*/
private void startup(){
System.out.println("启动工作线程。。。");
synchronized(taskQueue){
for(int i = 0; i < DEFAULT_POOL_SIZE; i++){
WorkThread workThread = new WorkThread(taskQueue);
threadPool.add( workThread );
workThread.start();
}
}
}
/**
* 停止工作线程。工作线程不一定立即停止,只有在线程处于运行状态时会立即停止
*/
public void shutdown(){
System.out.println("停止工作线程.");
synchronized(taskQueue){
for(int i = 0; i < DEFAULT_POOL_SIZE; i++){
threadPool.get(i).shutdown();
}
}
}
/**
* 添加消息到队尾,
*/
public void addTask(Task task){
synchronized(taskQueue){
taskQueue.add(task);
taskQueue.notifyAll();
}
}
}
[/code]
[b]二 工作线程---WorkerThread[/b] 顾名思义 它本身就是一个线程,而且是专门用来工作的,工作线程的主要任务是从任务队列中取出任务 然后执行任务
[code]/**
* 工作线程
* @author XuLiangYong
* Jul 20, 2007 3:47:52 PM
*/
public class WorkThread extends Thread{
private boolean shutdown = false;
private Queue<Task> queue;
public WorkThread(Queue<Task> queue){
this.queue = queue;
}
public void run(){
while(!shutdown){
synchronized(queue){ //获得对象锁 禁止其他线程访问
if(!queue.isEmpty()){
//处理任务
Task task = queue.poll();
task.execute();
}else{
try {
queue.wait(); //释放锁 线程处于阻赛状态 等待notify唤醒
} catch (InterruptedException e) {
}
}
}
}//end while
}
/**
* 调用该方法后不一定会立即结束线程, 只有在线程处于运行状态且处理完当前任务后才结束
*/
public void shutdown(){
shutdown = true;
}
}[/code]
[b]三 任务队列---TaskQueue[/b] FIFO数据结构 在出对入队的时候要[b]锁定对象[/b]避免两个线程重复处理某任务
在这里我采用的是java提供的ConcurrentLinkedQueue队列,这是一个用链表实现的队 可无限的扩大,具体用法请看doc
用到队列的地方主要有两个 addTask(Task task) 和 Task task = queue.poll();
[b]四 任务接口---Task[/b] 任务接口只有一个方法 execute(),使用者只需实现这个接口就可以了
[code]public interface Task {
void execute();
}[/code]
用法:
[code]public class TestThreadPoolManager extends TestCase {
public void test(){
ThreadPoolManager pool = new ThreadPoolManager();
for(int i = 0; i < 100; i++){
pool.addTask(new SimpleTask(new MyManager(), i)); //SimpleTask实现了Task接口
}
pool.shutdown();
}
}[/code]
可以看出用户的使用非常简单
在jdk5中 java提供了线程池 有时间再写一个jdk5的线程池的例子
有一点注意 千万不要在servlet中调用线程池 因为servlet本来就是一个线程池
一个线程池由线程池管理器 工作线程 任务队列和任务接口组成
[b]一 线程池管理器[/b]---ThreadPoolMananger 主要负责启动 停止工作线程
[code]public class ThreadPoolManager {
private static int DEFAULT_POOL_SIZE = 4;
private List<WorkThread> threadPool;
private Queue<Task> taskQueue;
private int poolSize;
public ThreadPoolManager(){
this(DEFAULT_POOL_SIZE);
}
public ThreadPoolManager(int poolSize){
if(poolSize <= 0){
this.poolSize = DEFAULT_POOL_SIZE;
}else{
this.poolSize = poolSize;
}
threadPool = new ArrayList<WorkThread>(this.poolSize);
taskQueue = new ConcurrentLinkedQueue<Task>();
startup();
}
/**
* 启动线程池 开始处理任务
*/
private void startup(){
System.out.println("启动工作线程。。。");
synchronized(taskQueue){
for(int i = 0; i < DEFAULT_POOL_SIZE; i++){
WorkThread workThread = new WorkThread(taskQueue);
threadPool.add( workThread );
workThread.start();
}
}
}
/**
* 停止工作线程。工作线程不一定立即停止,只有在线程处于运行状态时会立即停止
*/
public void shutdown(){
System.out.println("停止工作线程.");
synchronized(taskQueue){
for(int i = 0; i < DEFAULT_POOL_SIZE; i++){
threadPool.get(i).shutdown();
}
}
}
/**
* 添加消息到队尾,
*/
public void addTask(Task task){
synchronized(taskQueue){
taskQueue.add(task);
taskQueue.notifyAll();
}
}
}
[/code]
[b]二 工作线程---WorkerThread[/b] 顾名思义 它本身就是一个线程,而且是专门用来工作的,工作线程的主要任务是从任务队列中取出任务 然后执行任务
[code]/**
* 工作线程
* @author XuLiangYong
* Jul 20, 2007 3:47:52 PM
*/
public class WorkThread extends Thread{
private boolean shutdown = false;
private Queue<Task> queue;
public WorkThread(Queue<Task> queue){
this.queue = queue;
}
public void run(){
while(!shutdown){
synchronized(queue){ //获得对象锁 禁止其他线程访问
if(!queue.isEmpty()){
//处理任务
Task task = queue.poll();
task.execute();
}else{
try {
queue.wait(); //释放锁 线程处于阻赛状态 等待notify唤醒
} catch (InterruptedException e) {
}
}
}
}//end while
}
/**
* 调用该方法后不一定会立即结束线程, 只有在线程处于运行状态且处理完当前任务后才结束
*/
public void shutdown(){
shutdown = true;
}
}[/code]
[b]三 任务队列---TaskQueue[/b] FIFO数据结构 在出对入队的时候要[b]锁定对象[/b]避免两个线程重复处理某任务
在这里我采用的是java提供的ConcurrentLinkedQueue队列,这是一个用链表实现的队 可无限的扩大,具体用法请看doc
用到队列的地方主要有两个 addTask(Task task) 和 Task task = queue.poll();
[b]四 任务接口---Task[/b] 任务接口只有一个方法 execute(),使用者只需实现这个接口就可以了
[code]public interface Task {
void execute();
}[/code]
用法:
[code]public class TestThreadPoolManager extends TestCase {
public void test(){
ThreadPoolManager pool = new ThreadPoolManager();
for(int i = 0; i < 100; i++){
pool.addTask(new SimpleTask(new MyManager(), i)); //SimpleTask实现了Task接口
}
pool.shutdown();
}
}[/code]
可以看出用户的使用非常简单
在jdk5中 java提供了线程池 有时间再写一个jdk5的线程池的例子
有一点注意 千万不要在servlet中调用线程池 因为servlet本来就是一个线程池