如何用利特爾法則調整執行緒池大小
阿新 • • 發佈:2020-05-27
## 利特爾法則
利特爾法則派生於**排隊論**,用以下數學公式表示:
L = λW
L 系統中存在的平均請求數量。
λ 請求有效到達速率。例如:5/s 表示每秒有5個請求到達系統。
W 請求在系統中的平均等待執行時間。
> 排隊論:研究服務系統中排隊現象隨機規律的學科,探究排隊有關的數量指標的概率規律性。
## 場景
我們先假設一個店鋪員工調整場景。
#### 前提
- 每個客戶一次只買一隻炸雞;
- 每位員工製作一個炸雞需要1分鐘。
- 客戶買炸雞時等待時間越短,體驗越好。
如果你是一家炸雞店老闆,今年受疫情影響需要對店裡的員工進行調整,你會如何處理?
這個問題本質就是**員工利用率**與**客戶體驗**之間的權衡。
1. 為了讓客戶保持極佳體驗,需要保持員工數量或增加員工;
2. 為避免資源浪費,控制人力成本,需要裁減空閒員工。
假設店裡目前有3名員工。你如何進行員工調整決策。我們分析以下幾種情形。
當 **平均客流量 = 3人/分鐘** 客戶等待時間稍短,體驗良好,並且員工工作都是飽和。此時不需要調整。
![=3人/分鐘](https://upload-images.jianshu.io/upload_images/19724385-d4d26e432982101b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
當 **平均客流量 < 3人/分鐘** 客戶等待時間稍短,體驗良好,但是始終有一個員工在打醬油,此時可以考慮減裁一人。
![< 3人/分鐘](https://upload-images.jianshu.io/upload_images/19724385-09a76078b8a8df4e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
當 **平均客流量 > 3人/分鐘** 客戶5,6,7等待時間延長體驗稍差,此時可以根據實際情況增加員工。
![客流量 > 3人/分鐘](https://upload-images.jianshu.io/upload_images/19724385-1e9be3b0e6af2731.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**平均每分鐘客流量 ≈ 員工數** 為最佳。
## 執行緒池
其實執行緒池處理也算是一個排隊模型。簡化Java執行緒池處理模型如下:
執行緒池任務執行大致階段:提交 --> 入佇列或直接執行 ---> 實際執行
![執行緒池](https://upload-images.jianshu.io/upload_images/19724385-9b084956bb5496ba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- **任務提交頻率**:每秒任務提交數;
- **任務佇列等待平均耗時**:任務佇列等待總耗時除以實際執行數;
- **任務實際執行平均耗時**:任務實際執行總耗時除以實際執行數;
- **任務執行平均耗時**:任務佇列等待平均耗時加任務實際執行平均耗時;
我們可以根據以下指標來評估調整執行緒池引數
**執行緒池中平均任務數** = **任務提交頻率** * **任務執行平均耗時**
**執行緒等待耗時與響應時間比率** = **任務佇列等待總耗時** / (**任務佇列等待總耗時** + **任務實際執行總耗時**)
------
當 **執行緒等待耗時與響應時間比率** 過高,說明任務排隊較多,評估當前執行緒池大小是否合理,結合系統負載進行相應調整。
當 **執行緒池中平均任務數** < **目前執行緒池大小** 應適當減少執行緒數量。
當 **系統平均處理任務數** > **目前執行緒池大小** 在這種情況下,先評估當前系統是否有能力支撐更大的執行緒數量(如CPU數,記憶體等),然後再進行調整。
## 程式碼片段
```java
@Slf4j
public class MonitoredThreadPoolExecutor extends ThreadPoolExecutor {
//任務提交成功時間
private final Concurren