Xuất phát từ tỉ lệ thời gian chờ trên thời gian tính toán của task, công thức tham chiếu của Brian Goetz:
size = Ncpu * Ucpu * (1 + W/C)Ncpu=Runtime.getRuntime().availableProcessors()Ucpu= mức sử dụng CPU mục tiêu (0..1)W/C= thời gian chờ / thời gian tính
Task CPU-bound (mã hoá, tính toán, parse): W/C gần 0 → size ≈ Ncpu (hoặc Ncpu + 1). Thêm thread chỉ tăng context switch chứ không tăng thông lượng.
Task IO-bound (gọi HTTP, truy vấn DB): thread nằm chờ phần lớn thời gian. Nếu chờ 90ms, tính 10ms thì W/C = 9 → khoảng 10 * Ncpu.
Ba lưu ý thực chiến:
- Tách pool theo loại task. Trộn task IO chậm với task CPU nhanh trong một pool khiến task nhanh bị xếp hàng sau task chậm.
- Công thức chỉ là điểm khởi đầu; chốt số bằng đo thông lượng và p99 latency dưới tải thật.
- Trần thật thường không nằm ở thread: connection pool DB 20 kết nối thì pool 200 thread chỉ dồn chờ ở chỗ khác. Cân số thread khớp với tài nguyên hạ nguồn.