平時使用了哪些線程池

  • 閱讀完本篇文章會知道以下三點:
  • 1.進程-線程簡單介紹
  • 2.java的線程池是什麼,有哪些類型,做用分別是什麼
  • 3.使用線程池的優勢
  •  
  • 1.進程-線程的簡單介紹
  • 進程
  • 什麼是進程呢?
  • 進程是計算機中的程序關於某數據集合的一次運行活動,是系統進行資源分配的調度的基本單位,是操做系統結構的基礎。簡單來說:進程是指運行中的應用程序,進程是一個實體,每個進程都有它本身的地址空間。例如咱們點擊了QQ,就啓動了一個進程,操做系統就會爲這個進程分配獨立的地址空間,當咱們又點擊瀏覽器,這樣又啓動了一個進程,操做系統將爲新的進程分配新的獨立的地址空間。
  • 線程
  • 什麼是線程呢?
  • 線程是操做系統可以進行運算調度的最小單位,被包含在進程之中,是進程中的實際運做單位。一個進程至少有一個線程。一條線程指的是進程中一個單一順序的控制流,一個進程中能夠併發多個線程,每條線程並行執行不一樣的任務。注意:線程本身不擁有系統資源,只擁有一點在運行中必不可少的資源,但它可與同屬於一個進程的其餘線程共享進程所擁有的所有資源,線程有就緒,阻塞,運行三種基本狀態。
  • 另外:在Unix System和SunOS中也被稱爲輕量進程,但輕量進程更多指內核線程,而把用戶線程稱爲線程。
  • 2.java的線程池是什麼,有哪些類型,做用分別是什麼
  • 線程池是一種多線程處理形式,處理過程當中將任務添加隊列,而後在建立線程後自動啓動這些任務,每一個線程都使用默認的堆棧大小,以默認的優先級運行,並處在多線程單元中,若是某個線程在託管代碼中空閒,則線程池將插入另外一個輔助線程來使全部處理器保持繁忙。若是全部線程池都始終保持繁忙,但隊列中包含掛起的工做,則線程池將在一段時間後輔助線程的數目永遠不會超過最大值。超過最大值的線程能夠排隊,但他們要等到其餘線程完成後才能啓動。
  • java裏面的線程池的頂級接口是Executor,Executor並非一個線程池,而只是一個執行線程的工具,而真正的線程池是ExecutorService。
  • java中的有哪些線程池?
  • 1.newCachedThreadPool建立一個可緩存線程池程
  • 2.newFixedThreadPool 建立一個定長線程池
  • 3.newScheduledThreadPool 建立一個定長線程池
  • 4.newSingleThreadExecutor 建立一個單線程化的線程池
  • 下面一一分析:
  • 1.newCachedThreadPool,是一種線程數量不定的線程池,而且其最大線程數爲Integer.MAX_VALUE,這個數是很大的,一個可緩存線程池,若是線程池長度超過處理須要,可靈活回收空閒線程,若無可回收,則新建線程。可是線程池中的空閒線程都有超時限制,這個超時時長是60秒,超過60秒閒置線程就會被回收。調用execute將重用之前構造的線程(若是線程可用)。這類線程池比較適合執行大量的耗時較少的任務,當整個線程池都處於閒置狀態時,線程池中的線程都會超時被中止。
  • 實例代碼:
  •     public class PoolExecutorTest {
  •      
  •         public static void main(String[] args) {
  •             // TODO Auto-generated method stub
  •             
  •             ExecutorService mCachelThreadPool = Executors.newCachedThreadPool();
  •             
  •             for(int i = 0;i < 7;i++ ) {
  •                 final int index = i;
  •                 try {
  •                     Thread.sleep(2000);
  •                 } catch (InterruptedException e) {
  •                     e.printStackTrace();
  •                 }
  •                 mCachelThreadPool.execute(new Runnable() {
  •                     
  •                     @Override
  •                     public void run() {
  •                         System.out.println("第" +index +"個線程" +Thread.currentThread().getName());
  •                     }
  •                 });
  •                 
  •             }
  •             
  •      
  •         }
  •      
  •     }
  • 輸出結果:
  • 從結果能夠看到,執行第二個任務的時候第一個任務已經完成,會複用執行第一個任務的線程,不用每次新建線程。
  • 2.newFixedThreadPool 建立一個指定工做線程數量的線程池,每當提交一個任務就建立一個工做線程,當線程 處於空閒狀態時,它們並不會被回收,除非線程池被關閉了,若是工做線程數量達到線程池初始的最大數,則將提交的任務存入到池隊列(沒有大小限制)中。因爲newFixedThreadPool只有核心線程而且這些核心線程不會被回收,這樣它更加快速底相應外界的請求。
  • 實例代碼:
  •     public class PoolExecutorTest {
  •      
  •         public static void main(String[] args) throws InterruptedException {
  •             // TODO Auto-generated method stub
  •             //設置最大線程數5個
  •             ExecutorService mFixedThreadPool = Executors.newFixedThreadPool(5);
  •             
  •             for(int i = 0;i < 7;i++ ) {
  •                 final int index = i;
  •                 mFixedThreadPool.execute(new Runnable() {
  •                     
  •                     @Override
  •                     public void run() {
  •                         System.out.println("時間是:"+System.currentTimeMillis()+"第" +index +"個線程" +Thread.currentThread().getName());
  •                         try {
  •                             Thread.sleep(2000);
  •                         } catch (InterruptedException e) {
  •                             e.printStackTrace();
  •                         }    
  •                      }
  •                 });
  •                 
  •             }
  •             
  •      
  •         }
  •      
  •     }
  • 輸出結果:
  • 因爲設置最大線程是5,因此當執行完這5個線程後,等待兩秒後,在執行後面2個線程。
  • 3.newScheduledThreadPool 建立一個線程池,它的核心線程數量是固定的,而非核心線程數是沒有限制的,而且當非核心線程閒置時會被當即回收,它可安排給定延遲後運行命令或者按期地執行。這類線程池主要用於執行定時任務和具備固定週期的重複任務。
  • 延遲執行實例代碼:
  •     public class PoolExecutorTest {
  •      
  •         public static void main(String[] args) throws InterruptedException {
  •             // TODO Auto-generated method stub
  •             
  •             //設置池中核心數量是2
  •             ScheduledExecutorService mScheduledThreadPool = Executors.newScheduledThreadPool(2);  
  •             System.out.println("如今的時間:"+System.currentTimeMillis());
  •             mScheduledThreadPool.schedule(new Runnable() {
  •                 
  •                 @Override
  •                 public void run() {
  •                     // TODO Auto-generated method stub
  •                     System.out.println("如今的時間:"+System.currentTimeMillis());
  •                     
  •                 }
  •             }, 4, TimeUnit.SECONDS);//這裏設置延遲4秒執行
  •             
  •      
  •         }
  •      
  •     }
  • 執行的結果以下:
  • 偏差能夠忽略,實際結果確實延遲了4秒執行。
  • 按期執行示例代碼
  •     public class PoolExecutorTest {
  •      
  •         public static void main(String[] args) throws InterruptedException {
  •             // TODO Auto-generated method stub
  •             
  •             //設置池中核心數量是2
  •             ScheduledExecutorService mScheduledThreadPool = Executors.newScheduledThreadPool(2);  
  •             System.out.println("如今的時間:"+System.currentTimeMillis());
  •             mScheduledThreadPool.scheduleAtFixedRate(new Runnable() {
  •                 
  •                 @Override
  •                 public void run() {
  •                     // TODO Auto-generated method stub
  •                     System.out.println("如今的時間:"+System.currentTimeMillis());
  •                     
  •                 }
  •             }, 2, 3,TimeUnit.SECONDS);//這裏設置延遲2秒後每3秒執行一次
  •             
  •      
  •         }
  •      
  •     }
  • 執行的結果以下:
  • 可發現確實延遲2秒後每隔3秒後就會執行一次,程序不退出就一直執行下去。
  • 4.newSingleThreadExecutor這類線程池內部只有一個核心線程,以無界隊列方式來執行該線程,這使得這些任務之間不須要處理線程同步的問題,它確保全部的任務都在同一個線程中按順序中執行,而且能夠在任意給定的時間不會有多個線程是活動的。
  • 示例代碼:
  •     public class PoolExecutorTest {
  •      
  •         public static void main(String[] args) throws InterruptedException {
  •             // TODO Auto-generated method stub
  •             
  •             ExecutorService mSingleThreadPool = Executors.newSingleThreadExecutor();     
  •             for(int i = 0;i < 7;i++) {
  •                 final int number = i;
  •                 mSingleThreadPool.execute(new Runnable() {
  •                     
  •                     @Override
  •                     public void run() {
  •                         System.out.println("如今的時間:"+System.currentTimeMillis()+"第"+number+"個線程");
  •                         try {
  •                             Thread.sleep(2000);
  •                         } catch (InterruptedException e) {
  •                             e.printStackTrace();
  •                         }
  •                         
  •                     }
  •                 });
  •                 
  •             }
  •      
  •         }
  •      
  •     }
  • 執行的結果以下:
  • 可發現是有順序地去執行上面6個線程。
  • 3.使用線程池的優勢
  • 1.重用線程池的線程,避免由於線程的建立和銷燬鎖帶來的性能開銷
  • 2.有效控制線程池的最大併發數,避免大量的線程之間因搶佔系統資源而阻塞
  • 3.可以對線程進行簡單的管理,並提供一下特定的操做如:能夠提供定時、按期、單線程、併發數控制等功能
  • ————————————————
  • 版權聲明:本文爲CSDN博主「真·深紅騎士」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
  • 原文連接:https://blog.csdn.net/qq_33453910/article/details/81413285
相關文章
相關標籤/搜索