天天看點

Java線程池應用及實作原理

為什麼要用線程池:

  1. 線程在java中是一個對象,更是作業系統的資源,線程的建立銷毀需要時間。如果建立+銷毀時間>執行任務時間就很不劃算。
  2. java對象占用堆記憶體,作業系統線程占用系統記憶體,根據jvm規範,一個線程預設最大棧大小為1M,這個棧空間是需要系統記憶體中配置設定的。是以線程過多,會消耗很多記憶體。
  3. 作業系統需要頻繁切換線程上下文,影響性能。

通過使用線程池可以控制線程數量,并且實作線程的重複利用。

線程池概念(元件)

  1. 線程池管理器:用于建立并管理線程池,包括建立線程,銷毀線程,添加新任務
  2. 工作線程:線程池中的執行任務的線程,在沒有任務時處于等待狀态,可以循環的執行任務
  3. 任務接口:每個任務必須實作的接口,以供工作線程排程任務的運作,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀态等
  4. 任務隊列:用于存放沒有被處理的任務,提供一種緩沖機制。

線程池接口定義和實作類

  • 接口  Executor  最上層的接口,定義了執行任務的方法execute(Runnable))
  • 接口  ExecutorService  繼承了Executor接口,拓展了Callable、Future、關閉等相關方法
  • 接口  ScheduledExecutorService  繼承了ExecutorService,增加了定時任務相關方法
  • 實作類  ThreadPoolExecutor  基礎、标準的線程池實作
  • 實作類  ScheduledTreadPoolExecutor  繼承了ThreadPoolExecutor,實作了ScheduledExecutorService中定時任務相關方法

标準線程池

參數:

  • corePoolSize(int):核心線程數
  • maximumPoolSize(int):最大線程數
  • keepAliveTime(long):超出核心線程數的線程等待存活時間
  • unit(TimeUnit):keepAliveTime時間機關
  • workQueue(BlockingQueue<Runnable>):任務隊列
  • threadFactury(ThreadFactory):線程建立工廠
  • handler(RejectedExecutionHandler):拒絕政策

任務執行流程:

  1. 是否達到核心線程數量?如果沒有達到,建立一個工作線程來執行任務
  2. 工作隊列是否已滿?如果沒滿,則将新送出的任務存儲在工作隊列裡
  3. 是否達到線程池最大數量?如果沒達到,則建立一個新的工作線程來執行任務
  4. 執行自定義或預設的抛出RejectedExecutionException拒絕政策來處理任務
Java線程池應用及實作原理

定時任務線程池

參數:

  • corePoolSize(int)  核心線程數
  • threadFactory(ThreadFactory)  線程建立工廠
  • handler(RejectedExecutionHandler)  拒絕政策

最大線程數為Integer.MAX_VALUE,存活時間為0,使用DelayWorkQueue延時隊列作為延時任務存放隊列。

定時任務使用方式:

scheduleAtFixedRate、scheduleWithFixedDelay

線程池的關閉

shutdown:線程池被關閉後,如果送出新任務,則會直接執行拒絕政策,但是會等待已有任務全部執行完成

shutdownNow:線程池被關閉後,無法送出新任務,并且會嘗試中斷有所正在執行的任務,傳回等待的任務清單

控制線程數量

一般使CPU使用率達到80%

計算行任務:cpu數量的1-2倍

I/O型任務:可以使用更多的線程,根據具體的I/O阻塞時長決定

繼續閱讀