在 Java 多线程中,**死锁(Deadlock)**通常是指:两个或多个线程彼此持有对方所需要的锁,并且都在等待对方释放锁,从而导致所有相关线程都无法继续执行。
下面从原因、示例、条件、避免方式几个方面说明。
死锁的本质是:线程之间对锁的获取顺序不一致 + 互相持有对方需要的资源。
例如:
结果:
public class DeadlockDemo {
private static final Object lockA = new Object();
private static final Object lockB = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lockA) {
System.out.println("Thread-1: hold lockA");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (lockB) {
System.out.println("Thread-1: hold lockB");
}
}
}).start();
new Thread(() -> {
synchronized (lockB) {
System.out.println("Thread-2: hold lockB");
try { Thread.sleep(100); } catch (InterruptedException e) {}
synchronized (lockA) {
System.out.println("Thread-2: hold lockA");
}
}
}).start();
}
}
结果:程序卡死,两个线程互相等待。
互斥条件
资源一次只能被一个线程占用(如 synchronized)
占有且等待
线程持有了资源,还在等待其他资源
不可抢占
线程已获得的锁不能被强制剥夺
循环等待
存在线程资源的循环依赖关系
✅ Java 中只要打破其中任意一个条件,就可以避免死锁。
// 线程1
synchronized(A) { synchronized(B) {} }
// 线程2
synchronized(B) { synchronized(A) {} }
外部方法可能再次加锁或阻塞。
ReentrantLock 但未正确释放lock.lock();
// 异常未 unlock
// 统一先拿 lockA,再拿 lockB
synchronized(lockA) {
synchronized(lockB) { }
}
tryLock(ReentrantLock)if (lock.tryLock()) {
try { ... } finally { lock.unlock(); }
}
ConcurrentHashMapBlockingQueueCountDownLatchSemaphorelock.tryLock(1, TimeUnit.SECONDS);
jstackjstack <pid>
会显示:
Found one Java-level deadlock
Java 多线程死锁的本质是:多个线程以不同顺序获取多个锁,导致循环等待。
如果你愿意,我可以:
synchronized vs ReentrantLock 的死锁差异免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。