Java線程池 Executor框架概述


線程池的意義

  1. 循環利用線程資源,避免重復創建和銷毀線程
  2. 線程池的任務是異步執行的,只要提交完成就能快速返回,可以提高應用響應性
  3. Java線程池還有一個很重要的意義:Java線程池就是JDK 5 推出的Executor框架,在此之前Java線程既是工作任務又是執行機制,而Executor框架把工作任務與執行機制分離開來:工作任務包括Runnable接口和Callable接口,而執行機制由Executor接口提供。

Executor 類繼承體系

Executor框架由三個部分組成

  1. 工作任務:Runnable/Callable 接口
    • 工作任務就是Runnable/Callable接口的實現,可以被線程池執行
  2. 執行機制:Executor接口、ExecutorService接口、ScheduledExecutorService接口
    • ThreadPoolExecutor 是最核心的線程池實現,用來執行被提交的任務
    • ScheduledThreadPoolExecutor 是任務調度的線程池實現,可以在給定的延遲后運行命令,或者定期執行命令(它比Timer更靈活)
    • ForkJoinPool是一個並發執行框架
  3. 異步計算的結果:Future接口
    • 實現Future接口的FutureTask類,代表異步計算的結果

線程池的實現原理

線程池的5個重要參數(需記牢):

  • workQueue:工作(任務)隊列
  • corePoolSize、maximumPoolSize:最小最大線程數
  • keepAliveTime:線程存活時間
  • threadFactory:線程工廠
  • handler:拒絕策略

  1. 如果運行的線程數少於corePoolSize,創建新線程來處理任務(注意,這一步需要獲取全局鎖)
  2. 否則,說明線程數大於corePoolSize,將任務插入BlockingQueue
  3. 如果插入任務失敗(隊列已滿),且運行的線程數少於maximumPoolSize,創建新線程來處理任務(注意,這一步需要獲取全局鎖)
  4. 否則,說明線程數大於maximumPoolSize,執行拒絕策略

ThreadPoolExecutor 采取上述設計思路,是為了盡可能地避免獲取全局鎖,在完成預熱之后(當前運行的線程數大於等於corePoolSize),則幾乎所有的調用都是執行步驟2,而步驟2不需要獲取全局鎖

關閉線程池

可以調用shutdown()或shutdownNow()來關閉線程池,其中原理是遍歷所有工作線程,然后逐個調用線程的interrupt()來進行中斷。但是它們存在一定的區別,shutdownNow首先將線程池的狀態設置成STOP,然后嘗試停止所有的正在執行或暫停任務的線程,並返回等待執行任務的列表,而shutdown只是將線程池的狀態設置成SHUTDOWN狀態,然后中斷所有沒有正在執行任務的線程。

只要調用了這兩個關閉方法中的任意一個,isShutdown()就會返回true。當所有的任務都關閉后,才表示線程池關閉成功,這時調用isTerminaed()會返回true。至於調用哪一種方法來關閉線程池,應該由線程池的任務特性決定,通常調用shutdown方法來關閉線程池,如果任務不一定要執行完,則可以調用shutdownNow方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM