精准复现锁竞争的关键是主动控制线程调度和断点时机:通过IDEA线程过滤断点、条件断点验证锁状态、暂停/恢复线程观察持有链、日志与断点联动标记锁生命周期。

要精准复现锁竞争的执行现场,关键不是“等它发生”,而是主动控制线程调度和断点触发时机——靠 IDE 的线程级断点策略 + 锁行为标记配合,才能把竞态从概率事件变成可重现的调试路径。
按线程名/状态过滤断点,锁定目标线程
默认断点会在所有线程命中,容易干扰。在 IntelliJ IDEA 中,右键断点 → “More” → 勾选 “Thread filter”,输入线程名(如 "worker-1" 或正则 "Thread-\d+");也可设为仅在 WAITING / BLOCKED 状态下触发,这样断点只停在尝试获取锁却被阻塞的瞬间,直接定位争抢现场。
用条件断点绑定锁对象状态
单纯停在 synchronized 或 lock.lock() 行还不够,得确认“此刻是否真有竞争”。例如:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 对
synchronized(obj),设条件断点:obj.hashCode() == 123456789 && Thread.holdsLock(obj) == false(即该锁正被他人持有,当前线程将阻塞) - 对
ReentrantLock,可在lock.tryLock()后加条件断点:!lock.isHeldByCurrentThread() && lock.hasQueuedThreads(),表示已有其他线程排队等待
结合“暂停所有线程”+“单独恢复”观察锁持有链
IDEA 调试器中点击“Pause Program”会挂起全部线程,此时展开“Threads”面板,能看到每个线程的栈帧里是否卡在 Unsafe.park、Object.wait 或 AbstractQueuedSynchronizer.acquire 等锁相关调用上。选中一个 BLOCKED 线程 → 右键 → “Resume”,它就会立刻尝试抢锁;再观察另一个正在持有锁的线程栈顶是否在临界区内部——这就构成了完整的竞争快照。
立即学习“Java免费学习笔记(深入)”;
用日志+断点联动标记锁生命周期
在 lock.lock() 前、临界区入口、unlock() 后分别插入带线程标识的日志(如 log.info("[{}] LOCK acquired", Thread.currentThread().getName())),同时在对应行设断点。开启“View Breakpoints” → 勾选 “Log evaluated expression”,输入 Thread.currentThread().getName() + " entered critical section"。这样每次断点命中时自动打印上下文,配合堆栈,能清晰还原“谁持有了多久、谁在等、等了多久”。

















