java多線程之線程池

來源:互聯網
上載者:User

標籤:

   自JDK5之後,Java推出了一個並發包,java.util.concurrent,在Java開發中,我們接觸到了好多池的技術,String類的對象池、Integer的共用池、串連資料庫的串連池、Struts1.3的對象池等等,池的最終目的都是節約資源,以更小的開銷做更多的事情,從而提高效能。

        我們的web項目都是部署在伺服器上,瀏覽器端的每一個request就是一個線程,那麼伺服器需要並發的處理多個請求,就需要線程池技術,下面來看一下Java並發包下如何建立線程池。

        1.  建立一個可重用固定線程集合的線程池,以共用的無界隊列方式來運行這些線程。

1  ExecutorService threadPool = Executors.newFixedThreadPool(3);// 建立可以容納3個線程的線程池  

 

 

        2. 建立一個可根據需要建立新線程的線程池,但是在以前構造的線程可用時將重用它們。

1 ExecutorService threadPool = Executors.newCachedThreadPool();// 線程池的大小會根據執行的任務數動態分配  

 

        3. 建立一個使用單個 worker 線程的 Executor,以無界隊列方式來運行該線程。

1 ExecutorService threadPool = Executors.newSingleThreadExecutor();// 建立單個線程的線程池,如果當前線程在執行任務時突然中斷,則會建立一個新的線程替代它繼續執行任務  

 


        4. 建立一個可安排在給定延遲後運行命令或者定期地執行的線程池。

ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(3);// 效果類似於Timer定時器  

 

        每種線程池都有不同的使用情境,下面看一下這四種線程池使用起來有什麼不同。 

        1. FixedThreadPool

  

 1 import java.util.concurrent.ExecutorService;   2 import java.util.concurrent.Executors;   3 public class ThreadPoolTest {   4     public static void main(String[] args) {   5         ExecutorService threadPool = Executors.newFixedThreadPool(3);   6         for(int i = 1; i < 5; i++) {   7             final int taskID = i;   8             threadPool.execute(new Runnable() {   9                 public void run() {  10                     for(int i = 1; i < 5; i++) {  11                         try {  12                             Thread.sleep(20);// 為了測試出效果,讓每次任務執行都需要一定時間  13                         } catch (InterruptedException e) {  14                             e.printStackTrace();  15                         }  16                         System.out.println("第" + taskID + "次任務的第" + i + "次執行");  17                     }  18                 }  19             });  20         }  21         threadPool.shutdown();// 任務執行完畢,關閉線程池  22     }  23 }  

 

        輸出結果:

  1. 第1次任務的第1次執行  
  2. 第2次任務的第1次執行  
  3. 第3次任務的第1次執行  
  4. 第2次任務的第2次執行  
  5. 第3次任務的第2次執行  
  6. 第1次任務的第2次執行  
  7. 第3次任務的第3次執行  
  8. 第1次任務的第3次執行  
  9. 第2次任務的第3次執行  
  10. 第3次任務的第4次執行  
  11. 第2次任務的第4次執行  
  12. 第1次任務的第4次執行  
  13. 第4次任務的第1次執行  
  14. 第4次任務的第2次執行  
  15. 第4次任務的第3次執行  
  16. 第4次任務的第4次執行  

        上段代碼中,建立了一個固定大小的線程池,容量為3,然後迴圈執行了4個任務,由輸出結果可以看到,前3個任務首先執行完,然後空閑下來的線程去執行第4個任務,在FixedThreadPool中,有一個固定大小的池,如果當前需要執行的任務超過了池大小,那麼多於的任務等待狀態,直到有空閑下來的線程執行任務,而當執行的任務小於池大小,閒置線程也不會去銷毀
        2. CachedThreadPool

 

        上段代碼其它地方不變,將newFixedThreadPool方法換成newCachedThreadPool方法。

        輸出結果:

  1. 第3次任務的第1次執行  
  2. 第4次任務的第1次執行  
  3. 第1次任務的第1次執行  
  4. 第2次任務的第1次執行  
  5. 第4次任務的第2次執行  
  6. 第3次任務的第2次執行  
  7. 第2次任務的第2次執行  
  8. 第1次任務的第2次執行  
  9. 第2次任務的第3次執行  
  10. 第3次任務的第3次執行  
  11. 第1次任務的第3次執行  
  12. 第4次任務的第3次執行  
  13. 第2次任務的第4次執行  
  14. 第4次任務的第4次執行  
  15. 第3次任務的第4次執行  
  16. 第1次任務的第4次執行  

     可見,4個任務是交替執行的,CachedThreadPool會建立一個緩衝區,將初始化的線程緩衝起來,如果線程有可用的,就使用之前建立好的線程,如果沒有可用的,就新建立線程,終止並且從緩衝中移除已有60秒未被使用的線程

 

        3. SingleThreadExecutor        

       上段代碼其它地方不變,將newFixedThreadPool方法換成newSingleThreadExecutor方法。       

       輸出結果:

 

 
  1. 第1次任務的第1次執行  
  2. 第1次任務的第2次執行  
  3. 第1次任務的第3次執行  
  4. 第1次任務的第4次執行  
  5. 第2次任務的第1次執行  
  6. 第2次任務的第2次執行  
  7. 第2次任務的第3次執行  
  8. 第2次任務的第4次執行  
  9. 第3次任務的第1次執行  
  10. 第3次任務的第2次執行  
  11. 第3次任務的第3次執行  
  12. 第3次任務的第4次執行  
  13. 第4次任務的第1次執行  
  14. 第4次任務的第2次執行  
  15. 第4次任務的第3次執行  
  16. 第4次任務的第4次執行  

        4個任務是順序執行的,SingleThreadExecutor得到的是一個單個的線程,這個線程會保證你的任務執行完成,如果當前線程意外終止,會建立一個新線程繼續執行任務,這和我們直接建立線程不同,也和newFixedThreadPool(1)不同。

 

    4.ScheduledThreadPool    

 

 1 import java.util.concurrent.ScheduledExecutorService;   2 import java.util.concurrent.TimeUnit;   3 public class ThreadPoolTest {   4     public static void main(String[] args) {   5         ScheduledExecutorService schedulePool = Executors.newScheduledThreadPool(1);   6         // 5秒後執行任務   7         schedulePool.schedule(new Runnable() {   8             public void run() {   9                 System.out.println("爆炸");  10             }  11         }, 5, TimeUnit.SECONDS);  12         // 5秒後執行任務,以後每2秒執行一次  13         schedulePool.scheduleAtFixedRate(new Runnable() {  14             @Override  15             public void run() {  16                 System.out.println("爆炸");  17             }  18         }, 5, 2, TimeUnit.SECONDS);  19     }  20 }  

 

 

        ScheduledThreadPool可以定時的或延時的執行任務。

        Java的並發包很強大,上面所說只是入門,隨著學習深入,會有更多記錄在部落格裡。

        本文來自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7443324,轉載請註明。

java多線程之線程池

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.