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, 評(píng)論 - 3, 引用 - 0

          導(dǎo)航

          <2008年9月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          blog收藏

          文件共享

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          線程池的實(shí)現(xiàn)

          線程池也許很多比較陌生 但是提到servlet每個(gè)人都知道,servlet就是用線程池來(lái)處理請(qǐng)求的
          一個(gè)線程池由線程池管理器 工作線程 任務(wù)隊(duì)列和任務(wù)接口組成
          一 線程池管理器---ThreadPoolMananger 主要負(fù)責(zé)啟動(dòng) 停止工作線程
          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.      * 啟動(dòng)線程池 開(kāi)始處理任務(wù)  
          27.      */  
          28.     private void startup(){   
          29.         System.out.println("啟動(dòng)工作線程。。。");   
          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.      * 停止工作線程。工作線程不一定立即停止,只有在線程處于運(yùn)行狀態(tài)時(shí)會(huì)立即停止  
          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.      * 添加消息到隊(duì)尾,    
          54.      */  
          55.     public void addTask(Task task){   
          56.         synchronized(taskQueue){   
          57.             taskQueue.add(task);   
          58.             taskQueue.notifyAll();     
          59.         }   
          60.     }   
          61.   
          62. }  

          二 工作線程---WorkerThread 顧名思義 它本身就是一個(gè)線程,而且是專門(mén)用來(lái)工作的,工作線程的主要任務(wù)是從任務(wù)隊(duì)列中取出任務(wù) 然后執(zhí)行任務(wù)

        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){ //獲得對(duì)象鎖 禁止其他線程訪問(wèn)   
        17.                 if(!queue.isEmpty()){   
        18.                     //處理任務(wù)    
        19.                     Task task = queue.poll();   
        20.                     task.execute();   
        21.                 }else{   
        22.                     try {   
        23.                         queue.wait(); //釋放鎖 線程處于阻賽狀態(tài) 等待notify喚醒   
        24.                     } catch (InterruptedException e) {   
        25.                     }   
        26.                 }   
        27.             }   
        28.         }//end while   
        29.     }   
        30.        
        31.     /**  
        32.      * 調(diào)用該方法后不一定會(huì)立即結(jié)束線程, 只有在線程處于運(yùn)行狀態(tài)且處理完當(dāng)前任務(wù)后才結(jié)束  
        33.      */  
        34.     public void shutdown(){   
        35.         shutdown = true;   
        36.     }   
        37. }  
        38.  

          三 任務(wù)隊(duì)列---TaskQueue FIFO數(shù)據(jù)結(jié)構(gòu) 在出對(duì)入隊(duì)的時(shí)候要鎖定對(duì)象避免兩個(gè)線程重復(fù)處理某任務(wù)
          在這里我采用的是java提供的ConcurrentLinkedQueue隊(duì)列,這是一個(gè)用鏈表實(shí)現(xiàn)的隊(duì) 可無(wú)限的擴(kuò)大,具體用法請(qǐng)看doc
          用到隊(duì)列的地方主要有兩個(gè) addTask(Task task) 和 Task task = queue.poll();


          四 任務(wù)接口---Task 任務(wù)接口只有一個(gè)方法 execute(),使用者只需實(shí)現(xiàn)這個(gè)接口就可以了

        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實(shí)現(xiàn)了Task接口   
        49.         }   
        50.         pool.shutdown();   
        51.     }   
        52.        
        53. 可以看出用戶的使用非常簡(jiǎn)單
          在jdk5中 java提供了線程池
          有一點(diǎn)注意 千萬(wàn)不要在servlet中調(diào)用線程池 因?yàn)閟ervlet本來(lái)就是一個(gè)線程池




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

          主站蜘蛛池模板: 衡阳县| 湄潭县| 瑞安市| 尚志市| 库尔勒市| 金寨县| 铜梁县| 桦甸市| 新建县| 无棣县| 龙门县| 合山市| 北流市| 五华县| 清新县| 樟树市| 尤溪县| 邮箱| 波密县| 中江县| 通化市| 静宁县| 泌阳县| 鄂尔多斯市| 陆川县| 准格尔旗| 东方市| 故城县| 龙海市| 蓬安县| 新巴尔虎右旗| 清涧县| 顺平县| 嘉荫县| 年辖:市辖区| 盘山县| 梅河口市| 玉山县| 枣庄市| 九江县| 池州市|