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)  編輯  收藏 所屬分類: 多線程

          主站蜘蛛池模板: 乌鲁木齐县| 平陆县| 马公市| 宜昌市| 嘉黎县| 丹阳市| 喀喇| 通化县| 三原县| 基隆市| 泌阳县| 舞钢市| 沙坪坝区| 宽甸| 满城县| 凤台县| 揭东县| 宣威市| 舒城县| 镶黄旗| 马尔康县| 清水县| 文登市| 扬中市| 突泉县| 班戈县| 通州市| 扎囊县| 扎兰屯市| 兴和县| 兰考县| 潞城市| 济源市| 筠连县| 阿拉善左旗| 夏津县| 乌恰县| 民乐县| 天津市| 玛曲县| 泾阳县|