ThreadPoolExecutor線程池參數設置技巧

1、ThreadPoolExecutor的重要參數性能

 

  • corePoolSize:核心線程數
    • 核心線程會一直存活,及時沒有任務須要執行
    • 當線程數小於核心線程數時,即便有線程空閒,線程池也會優先建立新線程處理
    • 設置allowCoreThreadTimeout=true(默認false)時,核心線程會超時關閉
  • queueCapacity:任務隊列容量(阻塞隊列)
    • 當核心線程數達到最大時,新任務會放在隊列中排隊等待執行
  • maxPoolSize:最大線程數
    • 當線程數>=corePoolSize,且任務隊列已滿時。線程池會建立新線程來處理任務
    • 當線程數=maxPoolSize,且任務隊列已滿時,線程池會拒絕處理任務而拋出異常
  • keepAliveTime:線程空閒時間
    • 當線程空閒時間達到keepAliveTime時,線程會退出,直到線程數量=corePoolSize
    • 若是allowCoreThreadTimeout=true,則會直到線程數量=0
  • allowCoreThreadTimeout:容許核心線程超時
  • rejectedExecutionHandler:任務拒絕處理器
    • 兩種狀況會拒絕處理任務:
      • 當線程數已經達到maxPoolSize,切隊列已滿,會拒絕新任務
      • 當線程池被調用shutdown()後,會等待線程池裏的任務執行完畢,再shutdown。若是在調用shutdown()和線程池真正shutdown之間提交任務,會拒絕新任務
    • 線程池會調用rejectedExecutionHandler來處理這個任務。若是沒有設置默認是AbortPolicy,會拋出異常
    • ThreadPoolExecutor類有幾個內部實現類來處理這類狀況:
      • AbortPolicy 丟棄任務,拋運行時異常
      • CallerRunsPolicy 執行任務
      • DiscardPolicy 忽視,什麼都不會發生
      • DiscardOldestPolicy 從隊列中踢出最早進入隊列(最後一個執行)的任務
    • 實現RejectedExecutionHandler接口,可自定義處理器

 

2、ThreadPoolExecutor執行順序:優化

     線程池按如下行爲執行任務.net

 

  1. 當線程數小於核心線程數時,建立線程。
  2. 當線程數大於等於核心線程數,且任務隊列未滿時,將任務放入任務隊列。
  3. 當線程數大於等於核心線程數,且任務隊列已滿
    1. 若線程數小於最大線程數,建立線程
    2. 若線程數等於最大線程數,拋出異常,拒絕任務

 

3、如何設置參數線程

 

  • 默認值
    • corePoolSize=1
    • queueCapacity=Integer.MAX_VALUE
    • maxPoolSize=Integer.MAX_VALUE
    • keepAliveTime=60s
    • allowCoreThreadTimeout=false
    • rejectedExecutionHandler=AbortPolicy()
  • 如何來設置
    • 須要根據幾個值來決定
      • tasks :每秒的任務數,假設爲500~1000
      • taskcost:每一個任務花費時間,假設爲0.1s
      • responsetime:系統容許容忍的最大響應時間,假設爲1s
    • 作幾個計算
      • corePoolSize = 每秒須要多少個線程處理? 
        • threadcount = tasks/(1/taskcost) =tasks*taskcout =  (500~1000)*0.1 = 50~100 個線程。corePoolSize設置應該大於50
        • 根據8020原則,若是80%的每秒任務數小於800,那麼corePoolSize設置爲80便可
      • queueCapacity = (coreSizePool/taskcost)*responsetime
        • 計算可得 queueCapacity = 80/0.1*1 = 80。意思是隊列裏的線程能夠等待1s,超過了的須要新開線程來執行
        • 切記不能設置爲Integer.MAX_VALUE,這樣隊列會很大,線程數只會保持在corePoolSize大小,當任務陡增時,不能新開線程來執行,響應時間會隨之陡增。
      • maxPoolSize = (max(tasks)- queueCapacity)/(1/taskcost)
        • 計算可得 maxPoolSize = (1000-80)/10 = 92
        • (最大任務數-隊列容量)/每一個線程每秒處理能力 = 最大線程數
      • rejectedExecutionHandler:根據具體狀況來決定,任務不重要可丟棄,任務重要則要利用一些緩衝機制來處理
      • keepAliveTime和allowCoreThreadTimeout採用默認一般能知足
  • 以上都是理想值,實際狀況下要根據機器性能來決定。若是在未達到最大線程數的狀況機器cpu load已經滿了,則須要經過升級硬件(呵呵)和優化代碼,下降taskcost來處理。

 

 

參考:blog

http://blog.csdn.net/zhouhl_cn/article/details/7392607接口

http://my.oschina.net/u/169390/blog/97415隊列

相關文章
相關標籤/搜索