线程池参数详解
合理配置线程池是提升系统性能的关键。ThreadPoolExecutor的核心参数包括:
- corePoolSize:核心线程数,线程池 maintianed even if idle.
- maximumPoolSize:最大线程数,允许创建的线程上限。
- keepAliveTime:非核心线程的空闲存活时间。
- workQueue:任务队列,如 ArrayBlockingQueue, LinkedBlockingQueue。
- threadFactory:线程工厂,用于创建新线程。
- handler:拒绝策略,如 AbortPolicy, CallerRunsPolicy。
面试题陷阱:为什么推荐使用 LinkedBlockingQueue 而不是 ArrayBlockingQueue?因为 LinkedBlockingQueue 的吞吐量通常更高,但存在 OOM 风险,因为它默认容量为 Integer.MAX_VALUE。
synchronized vs ReentrantLock
两者都是可重入锁,但实现机制不同。
- ▶ synchronized:JVM层面的关键字,自动加锁解锁,不可中断,非公平锁。
- ▶ ReentrantLock:API层面的锁,需要手动 lock() 和 unlock(),支持公平锁,支持 Condition await/signal,支持尝试获取锁。
AQS (AbstractQueuedSynchronizer):ReentrantLock 的底层实现基于 AQS,它使用一个 int 类型的 state 变量表示同步状态,并通过 FIFO 队列管理等待线程。
CAS 与 ABA 问题
CAS (Compare And Swap) 是一种无锁算法,包含三个操作数:内存值V、旧的预期值A、要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
ABA 问题:如果一个值原来是A,变成了B,又变成了A,那么CAS检查时会认为它没有改变过。解决方案是使用 AtomicStampedReference,引入版本号(时间戳)来解决。