外观
线程池怎样创建才合理?
标准回答
根据任务性质、并发上限、队列容量、拒绝策略和生命周期设计线程池。CPU 密集任务避免线程数过多;阻塞 I/O 可以允许更多并发,但必须受到连接数、内存与下游承载能力限制。没有一个线程数公式适合所有 SDK。(ThreadPoolExecutor API)
机制解释
ThreadPoolExecutor 典型处理顺序是先增加到核心线程数,再尝试入队;队列满后才在最大线程数范围内扩容,最终可能拒绝。无界队列可能积压内存,也会让最大线程数难以发挥预期作用。
**代码练习一 有界任务池:**以下是机制示例,线程数和容量必须经实际压测决定。由 SDK 实例拥有并负责关闭,不要每次请求都创建新池。
java
ExecutorService ioPool = new ThreadPoolExecutor(
2, 4, 30, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(64),
new ThreadPoolExecutor.AbortPolicy());
try {
ioPool.execute(() -> performIo());
} catch (RejectedExecutionException e) {
reportBusy(); // 按约定线程通知调用方
}
// 由拥有者在资源释放阶段调用 ioPool.shutdown()延伸追问
CallerRunsPolicy 一定好吗?不一定。如果主线程提交任务,拒绝时就可能在主线程直接执行耗时任务。SDK 应有明确的忙碌错误或背压策略,而不是悄悄改变线程语义。
内容来源
- Android 智能硬件 SDK 技术 Wiki · 原条目
Q20