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 顧名思義 它本身就是一個線程,而且是專門用來工作的,工作線程的主要任務是從任務隊列中取出任務 然后執行任務

        1. /**  
        2.  * 工作線程  
        3.  * @author XuLiangYong  
        4.  * Jul 20, 2007 3:47:52 PM  
        5.  */  
        6. public class WorkThread extends Thread{   
        7.     private boolean shutdown = false;   
        8.     private Queue<Task> queue;   
        9.        
        10.     public WorkThread(Queue<Task> queue){   
        11.         this.queue = queue;   
        12.     }   
        13.        
        14.     public void run(){   
        15.         while(!shutdown){   
        16.             synchronized(queue){ //獲得對象鎖 禁止其他線程訪問   
        17.                 if(!queue.isEmpty()){   
        18.                     //處理任務    
        19.                     Task task = queue.poll();   
        20.                     task.execute();   
        21.                 }else{   
        22.                     try {   
        23.                         queue.wait(); //釋放鎖 線程處于阻賽狀態 等待notify喚醒   
        24.                     } catch (InterruptedException e) {   
        25.                     }   
        26.                 }   
        27.             }   
        28.         }//end while   
        29.     }   
        30.        
        31.     /**  
        32.      * 調用該方法后不一定會立即結束線程, 只有在線程處于運行狀態且處理完當前任務后才結束  
        33.      */  
        34.     public void shutdown(){   
        35.         shutdown = true;   
        36.     }   
        37. }  
        38.  

          三 任務隊列---TaskQueue FIFO數據結構 在出對入隊的時候要鎖定對象避免兩個線程重復處理某任務
          在這里我采用的是java提供的ConcurrentLinkedQueue隊列,這是一個用鏈表實現的隊 可無限的擴大,具體用法請看doc
          用到隊列的地方主要有兩個 addTask(Task task) 和 Task task = queue.poll();


          四 任務接口---Task 任務接口只有一個方法 execute(),使用者只需實現這個接口就可以了

        39. public interface Task {   
        40.     void execute();   
        41. }


        42. 用法:

        43. public class TestThreadPoolManager extends TestCase {   
        44.        
        45.     public void test(){   
        46.         ThreadPoolManager pool = new ThreadPoolManager();   
        47.         for(int i = 0; i < 100; i++){   
        48.             pool.addTask(new SimpleTask(new MyManager(), i)); //SimpleTask實現了Task接口   
        49.         }   
        50.         pool.shutdown();   
        51.     }   
        52.        
        53. 可以看出用戶的使用非常簡單
          在jdk5中 java提供了線程池
          有一點注意 千萬不要在servlet中調用線程池 因為servlet本來就是一個線程池




          張金鵬 2008-05-16 17:07 發表評論

          posted on 2008-09-07 11:10 大石頭 閱讀(219) 評論(0)  編輯  收藏 所屬分類: 多線程

          主站蜘蛛池模板: 海晏县| 道孚县| 绥宁县| 通河县| 桑植县| 吉林市| 竹北市| 千阳县| 成武县| 邵阳县| 东明县| 开封市| 永平县| 万州区| 美姑县| 和政县| 酒泉市| 汾西县| 方正县| 淮安市| 凌海市| 博乐市| 昌都县| 水城县| 吴川市| 嘉荫县| 健康| 平原县| 苍南县| 西畴县| 汤阴县| 肥东县| 习水县| 砀山县| 三台县| 黔西| 河间市| 闸北区| 南雄市| 连州市| 永年县|