死锁是大厂经常涉及的,下面我详解Java线程死锁以及解决方案@mikechen
Java线程死锁
线程死锁指的是:两个、或多个线程互相持有对方需要的资源。
并且都在等待对方释放资源,导致所有线程永久阻塞。

Thread-A
│
持有Lock-A
│
▼
等待 Lock-B ◄─────┐
│
│
Thread-B │
│ │
持有Lock-B │
│ │
▼ │
等待 Lock-A ──────┘
结果:
Thread-A 永远等待 Thread-B 永远等待
程序无法继续执行。
Java线程死锁解决方案

1. 统一加锁顺序
这是最有效、最常用的方法。
所有线程都按相同顺序获取锁,比如永远先拿 lockA 再拿 lockB。
// 示例:总是先获取hashCode小的锁
if (System.identityHashCode(lockA) < System.identityHashCode(lockB)) {
synchronized (lockA) { synchronized (lockB) { ... } }
} else {
synchronized (lockB) { synchronized (lockA) { ... } }
}
2. 尽量减少嵌套锁
能少拿一把锁就少拿一把锁,避免“持有 A 再申请 B”这种链式等待。
3. 缩小锁范围
把同步代码块缩到最小,只保护真正共享的数据,不要把 I/O、RPC、数据库访问、复杂计算放在持锁期间。
4. 使用超时锁
Lock.tryLock(timeout) 这类方式可以在等待超时后放弃获取锁,从而避免无限等待。
5. 设计成无锁或低锁
能用并发容器、原子类、消息队列、CAS、分段锁解决的,尽量不要靠粗粒度互斥锁硬扛。