锁性能取决于争用程度、临界区耗时、锁粒度和JVM优化:低并发下几乎无开销,高并发下易成瓶颈;应优先规避锁(不可变对象、ThreadLocal、原子类),再按场景选锁(synchronized适合简单同步,ReentrantLock支持超时与中断,StampedLock优化读多写少)。

线程同步锁不是“加了就安全,加了就慢”的黑箱。性能表现取决于争用程度、操作耗时、锁粒度和JVM运行时优化。低并发下加锁几乎无感,高并发下可能成为瓶颈——关键不在“用不用锁”,而在“怎么用才对”。
锁性能的核心影响因素
锁的开销不固定,它随场景动态变化:
- 争用水平:10个线程抢同一把锁,和1000个线程抢,等待队列长度、上下文切换次数呈非线性增长
- 临界区耗时:若同步块内只做一次整数加法(纳秒级),锁本身开销可能反超业务;若包含IO或复杂计算(毫秒级),锁等待占比反而下降
- 锁粒度:用一个全局锁保护整个订单服务,不如按用户ID分段加锁;粗粒度易阻塞,细粒度提升并发但增加管理成本
- JVM锁升级机制:Java 23+中,无竞争时偏向锁/轻量级锁几乎零开销;一旦发生竞争,会逐步升级为重量级锁,触发操作系统互斥原语,开销陡增
常见锁方案压测对比(1000线程,parse+format循环1万次)
真实压测数据揭示方案差异远超理论预期:
- 无保护:45ms,但错误率63%——快得毫无意义
- synchronized:380ms,0错误——可靠但吞吐受限,适合低频关键路径
- ThreadLocal:52ms,0错误——为每个线程独占实例,规避竞争,适用于不可变或线程隔离对象(如SimpleDateFormat)
- DateTimeFormatter(不可变):48ms,0错误——纯函数式设计,无状态,天然线程安全,是首选替代方案
实战压测的关键操作点
压测不是跑通就行,要模拟真实压力特征:
- 控制变量:固定CPU核心数、堆内存、GC策略(如ZGC),避免环境干扰
- 阶梯加压:从10线程开始,每次×2递增,观察耗时拐点与错误率突变,定位临界并发量
- 监控锁竞争:用JDK自带工具,如jstack -l查看BLOCKED线程数,jstat -gc排除GC干扰,VisualVM跟踪MonitorEnter耗时
- 区分锁类型场景:读多写少用StampedLock乐观读;需响应中断用ReentrantLock.tryLock();简单同步优先synchronized——JVM对其优化最成熟
性能优化的实用路径
不必一上来就换锁,先看能否绕过锁:
- 共享资源是否可改为不可变对象(如String、LocalDateTime、DateTimeFormatter)
- 能否用无锁原子类(AtomicInteger、LongAdder)替代计数器类同步
- 能否拆分锁:比如ConcurrentHashMap分段锁,或按key哈希分桶加锁
- 最后再选锁:低争用→synchronized;高争用+需超时→ReentrantLock;极致读性能→StampedLock


















