Java程式猿必會的四種執行緒池

好程式設計師IT發表於2019-07-10

前言,對於 Java 程式猿來說,執行緒池是面試高頻題,是我們必須掌握的一個技能,本篇文章主要給大家講解四種執行緒池的使用。

執行緒池簡介

  執行緒池的概念:

執行緒池就是首先建立一些執行緒,它們的集合稱為執行緒池。使用執行緒池可以很好地提高效能,執行緒池在系統啟動時即建立大量空閒的執行緒,程式將一個任務傳給執行緒池,執行緒池就會啟動一條執行緒來執行這個任務,執行結束以後,該執行緒並不會死亡,而是再次返回執行緒池中成為空閒狀態,等待執行下一個任務。

執行緒池的工作機制:

          線上程池的程式設計模式下,任務是提交給整個執行緒池,而不是直接提交給某個執行緒,執行緒池在拿到任務後,就在內部尋找是否有空閒的執行緒,如果有,則將任務交給某個空閒的執行緒。

          一個執行緒同時只能執行一個任務,但可以同時向一個執行緒池提交多個任務。

使用執行緒池的原因:

         多執行緒執行時間,系統不斷的啟動和關閉新執行緒,成本非常高,會過渡消耗系統資源,以及過渡切換執行緒的危險,從而可能導致系統資源的崩潰。這時,執行緒池就是最好的選擇了。


四種常見的執行緒池詳解

4.1  Executors.newCacheThreadPool()

Executors.newCacheThreadPool() :可快取執行緒池,先檢視池中有沒有以前建立的執行緒,如果有,就直接使用。如果沒有,就建一個新的執行緒加入池中,快取型池子通常用於執行一些生存期很短的非同步型任務

程式碼:

  1. import  java.util.concurrent.ExecutorService;  
  2. import  java.util.concurrent.Executors;  
  3. public   class  ThreadPoolExecutorTest {  
  4. public   static   void  main(String[] args) {  
  5. // 建立一個可快取執行緒池   
  6. ExecutorService cachedThreadPool = Executors.newCachedThreadPool();  
  7. for  ( int  i = 0; i < 10; i++) {  
  8. try  {  
  9. //sleep 可明顯看到使用的是執行緒池裡面以前的執行緒,沒有建立新的執行緒   
  10. Thread.sleep(1000);  
  11. catch  (InterruptedException e) {  
  12. e.printStackTrace();  
  13. }  
  14. cachedThreadPool.execute( new  Runnable() {  
  15. public   void  run() {  
  16. // 列印正在執行的快取執行緒資訊   
  17. System.out.println(Thread.currentThread().getName()+" 正在被執行 " );  
  18. }  
  19. });  
  20. }  
  21. }  
  22. }  

執行緒池為無限大,當執行當前任務時上一個任務已經完成,會複用執行上一個任務的執行緒,而不用每次新建執行緒

4.2   Executors.newFixedThreadPool(int n)

Executors.newFixedThreadPool(int n) :建立一個可重用固定個數的執行緒池,以共享的無界佇列方式來執行這些執行緒。

程式碼:

  1. package  com.study.test;  
  2. import  java.util.concurrent.ExecutorService;  
  3. import  java.util.concurrent.Executors;  
  4. public   class  ThreadPoolExecutorTest {  
  5. public   static   void  main(String[] args) {  
  6. // 建立一個可重用固定個數的執行緒池   
  7. ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);  
  8. for  ( int  i = 0; i < 10; i++) {  
  9. fixedThreadPool.execute( new  Runnable() {  
  10. public   void  run() {  
  11. try  {  
  12. // 列印正在執行的快取執行緒資訊   
  13. System.out.println(Thread.currentThread().getName()+" 正在被執行 " );  
  14. Thread.sleep(2000);  
  15. catch  (InterruptedException e) {  
  16. e.printStackTrace();  
  17. }  
  18. }  
  19. });  
  20. }  
  21. }  
  22. }  
  23. }  

 

4.3   Executors.newScheduledThreadPool(int n)

 Executors.newScheduledThreadPool(int n) :建立一個定長執行緒池,支援定時及週期性任務執行

程式碼:

  1. package  com.study.test;  
  2. import  java.util.concurrent.Executors;  
  3. import  java.util.concurrent.ScheduledExecutorService;  
  4. import  java.util.concurrent.TimeUnit;  
  5. public   class  ThreadPoolExecutorTest {  
  6. public   static   void  main(String[] args) {  
  7. // 建立一個定長執行緒池,支援定時及週期性任務執行 —— 延遲執行   
  8. ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  
  9. // 延遲 1 秒執行   
  10. scheduledThreadPool.schedule( new  Runnable() {  
  11. public   void  run() {  
  12. System.out.println(" 延遲 1 秒執行 " );  
  13. }  
  14. }, 1, TimeUnit.SECONDS);  
  15. }  
  16. }  

輸出結果:延遲 1 秒執行

 

程式碼 2 :可以定時執行

  1. package  com.study.test;  
  2. import  java.util.concurrent.Executors;  
  3. import  java.util.concurrent.ScheduledExecutorService;  
  4. import  java.util.concurrent.TimeUnit;  
  5. public   class  ThreadPoolExecutorTest {  
  6. public   static   void  main(String[] args) {  
  7. // 建立一個定長執行緒池,支援定時及週期性任務執行 —— 定期執行   
  8. ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  
  9. // 延遲 1 秒後每 3 秒執行一次   
  10. scheduledThreadPool.scheduleAtFixedRate( new  Runnable() {  
  11. public   void  run() {  
  12. System.out.println(" 延遲 1 秒後每 3 秒執行一次 " );  
  13. }  
  14. }, 1, 3, TimeUnit.SECONDS);  
  15. }  
  16. }  


4.4   Executors.newSingleThreadExecutor()

 Executors.newSingleThreadExecutor() :建立一個單執行緒化的執行緒池,它只會用唯一的工作執行緒來執行任務,保證所有任務按照指定順序 (FIFO, LIFO,  優先順序 ) 執行。

  1. package  com.study.test;  
  2. import  java.util.concurrent.ExecutorService;  
  3. import  java.util.concurrent.Executors;  
  4. public   class  TestThreadPoolExecutor {  
  5. public   static   void  main(String[] args) {  
  6. ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();  
  7. for  ( int  i = 0; i < 10; i++) {  
  8. final   int  index = i;  
  9. singleThreadExecutor.execute( new  Runnable() {  
  10. public   void  run() {  
  11. try  {  
  12. // 結果依次輸出,相當於順序執行各個任務   
  13. System.out.println(Thread.currentThread().getName()+" 正在被執行 , 列印的值是 :" +index);  
  14. Thread.sleep(1000);  
  15. catch  (InterruptedException e) {  
  16. e.printStackTrace();  
  17. }  
  18. }  
  19. });  
  20. }  
  21. }  
  22. }  


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2650127/,如需轉載,請註明出處,否則將追究法律責任。

相關文章