在 Java 中解决死锁问题通常需要结合代码设计、工具检测和预防策略。以下是详细的解决方案和最佳实践:
java复制// 不推荐:嵌套锁
synchronized (lockA) {
synchronized (lockB) { ... }
}
// 推荐:单锁或合并资源
synchronized (sharedLock) { ... }
java复制void transfer(Account from, Account to, int amount) {
Object first = from.hashCode() < to.hashCode() ? from : to;
Object second = from.hashCode() < to.hashCode() ? to : from;
synchronized (first) {
synchronized (second) {
// 转账逻辑
}
}
}
tryLock()
设置超时,失败后释放已有锁并重试。java复制Lock lockA = new ReentrantLock();
Lock lockB = new ReentrantLock();
if (lockA.tryLock(1, TimeUnit.SECONDS)) {
try {
if (lockB.tryLock(1, TimeUnit.SECONDS)) {
try {
// 业务逻辑
} finally {
lockB.unlock();
}
}
} finally {
lockA.unlock();
}
}
jstack <PID>
生成线程转储,查找 deadlock
关键词。AtomicInteger
等原子类。ConcurrentHashMap
等线程安全容器。CompletableFuture
或并行流(需注意线程池配置)。CyclicBarrier
/ CountDownLatch
替代手动锁。BlockingQueue
实现生产者-消费者模型。java复制public class DeadlockDemo {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock1) {
System.out.println("Thread1: Holding lock1");
try { Thread.sleep(10); } catch (InterruptedException e) {}
synchronized (lock2) {
System.out.println("Thread1: Acquired lock2");
}
}
});
Thread t2 = new Thread(() -> {
synchronized (lock1) { // 改为先获取 lock1,打破循环等待
System.out.println("Thread2: Holding lock1");
try { Thread.sleep(10); } catch (InterruptedException e) {}
synchronized (lock2) {
System.out.println("Thread2: Acquired lock2");
}
}
});
t1.start();
t2.start();
}
}
通过合理设计锁策略、使用工具检测和采用无锁编程,可以有效预防和解决 Java 中的死锁问题。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。