keep moving!

We must not cease from exploration. And the end of all our exploring will be to arrive where we began and to know the place for the first time.
随笔 - 37, 文章 - 2, 评论 - 3, 引用 - 0
数据加载中……

线程池的实现

线程池也许很多比较陌生 但是提到servlet每个人都知道,servlet就是用线程池来处理请求的
一个线程池由线程池管理器 工作线程 任务队列和任务接口组成
一 线程池管理器---ThreadPoolMananger 主要负责启动 停止工作线程
  1. public class ThreadPoolManager {   
  2.   
  3.     private static int DEFAULT_POOL_SIZE = 4;   
  4.     private List<WorkThread> threadPool;   
  5.     private Queue<Task> taskQueue;   
  6.     private int poolSize;   
  7.        
  8.     public ThreadPoolManager(){   
  9.         this(DEFAULT_POOL_SIZE);   
  10.     }   
  11.        
  12.     public ThreadPoolManager(int poolSize){   
  13.         if(poolSize <= 0){   
  14.             this.poolSize = DEFAULT_POOL_SIZE;   
  15.         }else{   
  16.             this.poolSize = poolSize;   
  17.         }   
  18.            
  19.         threadPool = new ArrayList<WorkThread>(this.poolSize);   
  20.         taskQueue = new ConcurrentLinkedQueue<Task>();   
  21.            
  22.         startup();   
  23.     }   
  24.        
  25.     /**  
  26.      * 启动线程池 开始处理任务  
  27.      */  
  28.     private void startup(){   
  29.         System.out.println("启动工作线程。。。");   
  30.         synchronized(taskQueue){   
  31.             for(int i = 0; i < DEFAULT_POOL_SIZE; i++){   
  32.                 WorkThread workThread = new WorkThread(taskQueue);   
  33.                 threadPool.add( workThread );   
  34.                 workThread.start();   
  35.             }   
  36.         }   
  37.            
  38.     }   
  39.        
  40.     /**  
  41.      * 停止工作线程。工作线程不一定立即停止,只有在线程处于运行状态时会立即停止  
  42.      */  
  43.     public void shutdown(){   
  44.         System.out.println("停止工作线程.");   
  45.         synchronized(taskQueue){   
  46.             for(int i = 0; i < DEFAULT_POOL_SIZE; i++){   
  47.                 threadPool.get(i).shutdown();   
  48.             }   
  49.         }   
  50.     }   
  51.        
  52.     /**  
  53.      * 添加消息到队尾,    
  54.      */  
  55.     public void addTask(Task task){   
  56.         synchronized(taskQueue){   
  57.             taskQueue.add(task);   
  58.             taskQueue.notifyAll();     
  59.         }   
  60.     }   
  61.   
  62. }  

二 工作线程---WorkerThread 顾名思义 它本身就是一个线程,而且是专门用来工作的,工作线程的主要任务是从任务队列中取出任务 然后执行任务

  • /**  
  •  * 工作线程  
  •  * @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;   
  •     }   
  • }  
  •  

    三 任务队列---TaskQueue FIFO数据结构 在出对入队的时候要锁定对象避免两个线程重复处理某任务
    在这里我采用的是java提供的ConcurrentLinkedQueue队列,这是一个用链表实现的队 可无限的扩大,具体用法请看doc
    用到队列的地方主要有两个 addTask(Task task) 和 Task task = queue.poll();


    四 任务接口---Task 任务接口只有一个方法 execute(),使用者只需实现这个接口就可以了

  • public interface Task {   
  •     void execute();   
  • }


  • 用法:

  • 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();   
  •     }   
  •        
  • 可以看出用户的使用非常简单
    在jdk5中 java提供了线程池
    有一点注意 千万不要在servlet中调用线程池 因为servlet本来就是一个线程池




    张金鹏 2008-05-16 17:07 发表评论

    posted on 2008-09-07 11:10 大石头 阅读(209) 评论(0)  编辑  收藏 所属分类: 多线程


    只有注册用户登录后才能发表评论。


    网站导航: