java 建立線程池(轉)

線程池的做用:javascript

     線程池做用就是限制系統中執行線程的數量。
     根據系統的環境狀況,能夠自動或手動設置線程數量,達到運行的最佳效果;少了浪費了系統資源,多了形成系統擁擠效率不高。用線程池控制線程數量,其餘線程排隊等候。一個任務執行完畢,再從隊列的中取最前面的任務開始執行。若隊列中沒有等待進程,線程池的這一資源處於等待。當一個新任務須要運行時,若是線程池中有等待的工做線程,就能夠開始運行了;不然進入等待隊列。
java

 

爲何要用線程池:web

  1. 減小了建立和銷燬線程的次數,每一個工做線程均可以被重複利用,可執行多個任務
  2. 能夠根據系統的承受能力,調整線程池中工做線線程的數目,防止由於由於消耗過多的內存,而把服務器累趴下(每一個線程須要大約1MB內存,線程開的越多,消耗的內存也就越大,最後死機)

線程池類服務器

    

Java代碼     收藏代碼
  1. package com.tdt.impl.ls;  
  2.   
  3. import java.util.LinkedList;  
  4.   
  5. /** 
  6.  * @project LocationGateway 
  7.  * @author sunnylocus    
  8.  * @verson 1.0.0 
  9.  * @date   Aug 2, 2008 
  10.  * @jdk    1.4.2 
  11.  */  
  12. public class ThreadPool extends ThreadGroup {  
  13.     private boolean isClosed = false;  //線程池是否關閉   
  14.     private LinkedList workQueue;      //工做隊列  
  15.     private static int threadPoolID = 1;  //線程池的id  
  16.     public ThreadPool(int poolSize) {  //poolSize 表示線程池中的工做線程的數量  
  17.   
  18.         super(threadPoolID + "");      //指定ThreadGroup的名稱  
  19.         setDaemon(true);               //繼承到的方法,設置是否守護線程池  
  20.         workQueue = new LinkedList();  //建立工做隊列  
  21.         for(int i = 0; i < poolSize; i++) {  
  22.             new WorkThread(i).start();   //建立並啓動工做線程,線程池數量是多少就建立多少個工做線程  
  23.         }  
  24.     }  
  25.       
  26.     /** 向工做隊列中加入一個新任務,由工做線程去執行該任務*/  
  27.     public synchronized void execute(Runnable task) {  
  28.         if(isClosed) {  
  29.             throw new IllegalStateException();  
  30.         }  
  31.         if(task != null) {  
  32.             workQueue.add(task);//向隊列中加入一個任務  
  33.             notify();           //喚醒一個正在getTask()方法中待任務的工做線程  
  34.         }  
  35.     }  
  36.       
  37.     /** 從工做隊列中取出一個任務,工做線程會調用此方法*/  
  38.     private synchronized Runnable getTask(int threadid) throws InterruptedException {  
  39.         while(workQueue.size() == 0) {  
  40.             if(isClosed) return null;  
  41.             System.out.println("工做線程"+threadid+"等待任務...");  
  42.             wait();             //若是工做隊列中沒有任務,就等待任務  
  43.         }  
  44.         System.out.println("工做線程"+threadid+"開始執行任務...");  
  45.         return (Runnable) workQueue.removeFirst(); //反回隊列中第一個元素,並從隊列中刪除  
  46.     }  
  47.       
  48.     /** 關閉線程池 */  
  49.     public synchronized void closePool() {  
  50.         if(! isClosed) {  
  51.             waitFinish();        //等待工做線程執行完畢  
  52.             isClosed = true;  
  53.             workQueue.clear();  //清空工做隊列  
  54.             interrupt();        //中斷線程池中的全部的工做線程,此方法繼承自ThreadGroup類  
  55.         }  
  56.     }  
  57.       
  58.     /** 等待工做線程把全部任務執行完畢*/  
  59.     public void waitFinish() {  
  60.         synchronized (this) {  
  61.             isClosed = true;  
  62.             notifyAll();            //喚醒全部還在getTask()方法中等待任務的工做線程  
  63.         }  
  64.         Thread[] threads = new Thread[activeCount()]; //activeCount() 返回該線程組中活動線程的估計值。  
  65.         int count = enumerate(threads); //enumerate()方法繼承自ThreadGroup類,根據活動線程的估計值得到線程組中當前全部活動的工做線程  
  66.         for(int i =0; i < count; i++) { //等待全部工做線程結束  
  67.             try {  
  68.                 threads[i].join();  //等待工做線程結束  
  69.             }catch(InterruptedException ex) {  
  70.                 ex.printStackTrace();  
  71.             }  
  72.         }  
  73.     }  
  74.   
  75.     /** 
  76.      * 內部類,工做線程,負責從工做隊列中取出任務,並執行 
  77.      * @author sunnylocus 
  78.      */  
  79.     private class WorkThread extends Thread {  
  80.         private int id;  
  81.         public WorkThread(int id) {  
  82.             //父類構造方法,將線程加入到當前ThreadPool線程組中  
  83.             super(ThreadPool.this,id+"");  
  84.             this.id =id;  
  85.         }  
  86.         public void run() {  
  87.             while(! isInterrupted()) {  //isInterrupted()方法繼承自Thread類,判斷線程是否被中斷  
  88.                 Runnable task = null;  
  89.                 try {  
  90.                     task = getTask(id);     //取出任務  
  91.                 }catch(InterruptedException ex) {  
  92.                     ex.printStackTrace();  
  93.                 }  
  94.                 //若是getTask()返回null或者線程執行getTask()時被中斷,則結束此線程  
  95.                 if(task == nullreturn;  
  96.                   
  97.                 try {  
  98.                     task.run();  //運行任務  
  99.                 }catch(Throwable t) {  
  100.                     t.printStackTrace();  
  101.                 }  
  102.             }//  end while  
  103.         }//  end run  
  104.     }// end workThread  
  105. }  

 

2.測試類app

  

Java代碼     收藏代碼
  1. package com.tdt.test;  
  2.   
  3. import com.tdt.impl.ls.ThreadPool;  
  4.   
  5. public class ThreadPoolTest {  
  6.       
  7.     public static void main(String[] args) throws InterruptedException {  
  8.         ThreadPool threadPool = new ThreadPool(3); //建立一個有個3工做線程的線程池  
  9.         Thread.sleep(500); //休眠500毫秒,以便讓線程池中的工做線程所有運行  
  10.         //運行任務  
  11.         for (int i = 0; i <=5 ; i++) { //建立6個任務  
  12.             threadPool.execute(createTask(i));  
  13.         }  
  14.         threadPool.waitFinish(); //等待全部任務執行完畢  
  15.         threadPool.closePool(); //關閉線程池  
  16.   
  17.     }  
  18.   
  19.     private static Runnable createTask(final int taskID) {  
  20.         return new Runnable() {  
  21.             public void run() {  
  22.             //  System.out.println("Task" + taskID + "開始");  
  23.                 System.out.println("Hello world");  
  24.             //  System.out.println("Task" + taskID + "結束");  
  25.             }  
  26.         };  
  27.     }  
  28. }  

 

 

結果:測試

Java代碼     收藏代碼
  1. 工做線程0等待任務...  
  2. 工做線程1等待任務...  
  3. 工做線程2等待任務...  
  4.   
  5. 工做線程0開始執行任務...  
  6. Hello world  
  7. 工做線程0等待任務...  
  8.   
  9. 工做線程1開始執行任務...  
  10. Hello world  
  11. 工做線程1等待任務...  
  12.   
  13. 工做線程2開始執行任務...  
  14. Hello world  
  15. 工做線程2等待任務...  
  16.   
  17. 工做線程0開始執行任務...  
  18. Hello world  
  19. 工做線程0等待任務...  
  20.   
  21. 工做線程1開始執行任務...  
  22. Hello world  
  23. 工做線程1等待任務...  
  24.   
  25. 工做線程2開始執行任務...  
  26. Hello world  
  27. 工做線程2等待任務...  

此上適用於jdk1.4版本。轉自 http://sunnylocus.iteye.com/blog/223327#commentsthis

相關文章
相關標籤/搜索