活锁是线程处于RUNNABLE状态、CPU占用高但任务原地打转;典型原因包括互相响应式退让、无延迟忙等待、确定性重试及协作逻辑缺陷;区别于死锁在于线程不阻塞而持续循环;应对需引入随机退避、最大重试限制、条件等待及职责分离。
活锁不是线程卡死,而是“忙得没进展”——线程始终处于 RUNNABLE 状态,CPU 占用高,但任务反复尝试、失败、再尝试,原地打转。
它不满足死锁的“阻塞”特征,却同样导致业务停滞。关键在于:线程未被挂起,却因过度谦让或响应式重试陷入无效循环。
tryLock() 失败后立即重试)看线程状态和 CPU 表现:
BLOCKED 或 WAITING,jstack 显示“waiting for monitor entry”,CPU 使用率低核心思路是打破“确定性同步响应”,引入异步、延迟或随机性,让至少一个线程能“抢跑”成功。
Thread.sleep(new Random().nextInt(100)),避免多线程整齐划一地撞车wait()/notify() 或 Condition.await() 替代 while + sleep,让线程真正挂起并由事件唤醒基本上就这些。活锁比死锁更隐蔽,但只要留意高 CPU + 无业务日志 + 线程持续 RUNNABLE 的组合,再结合代码里有没有“反复检查—失败—重试”模式,就能快速定位。