首頁>Club>
6
回覆列表
  • 1 # 詩和遠方vic

    一、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介面,可自定義處理器

    二、ThreadPoolExecutor執行順序

    執行緒池按以下行為執行任務

    (1)當執行緒數小於核心執行緒數時,建立執行緒。

    (2)當執行緒數大於等於核心執行緒數,且任務佇列未滿時,將任務放入任務佇列。

    (3)當執行緒數大於等於核心執行緒數,且任務佇列已滿

    1)若執行緒數小於最大執行緒數,建立執行緒

    2)若執行緒數等於最大執行緒數,丟擲異常,拒絕任務

    三、如何設定引數

    預設值

    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來處理。

  • 中秋節和大豐收的關聯?
  • 45歲以後,多吃三物,少做三事,記住5個字,可清除血管“垃圾”,說的是什麼?