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拒絕策略來處理任務

 

定時任務線程池

參數:

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

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

定時任務使用方式:

scheduleAtFixedRate、scheduleWithFixedDelay

 

線程池的關閉

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

shutdownNow:線程池被關閉後,無法提交新任務,並且會嘗試中斷有所正在執行的任務,返回等待的任務列表

 

控制線程數量

一般使CPU使用率達到80%

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章