细心!用心!耐心!

吾非文人,乃市井一俗人也,读百卷书,跨江河千里,故申城一游; 一两滴辛酸,三四年学业,五六点粗墨,七八笔买卖,九十道人情。

BlogJava 联系 聚合 管理
  1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
线程池也许很多比较陌生 但是提到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本来就是一个线程池


    posted on 2008-05-16 17:07 张金鹏 阅读(507) 评论(0)  编辑  收藏 所属分类: 多线程编程

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


    网站导航: