如何解决JAVA死锁
避免嵌套锁
减少锁的嵌套使用,尽量避免在一个同步块内持有多个锁。若必须使用多个锁,确保所有线程以相同的顺序获取锁,破坏死锁的循环等待条件。
使用定时锁
采用tryLock()方法替代内置锁机制,为锁操作设置超时时间。例如使用ReentrantLock的tryLock(long timeout, TimeUnit unit),在指定时间内未获取锁则主动释放资源。
Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();
if (lock1.tryLock(1, TimeUnit.SECONDS)) {
try {
if (lock2.tryLock(1, TimeUnit.SECONDS)) {
try {
// 临界区代码
} finally {
lock2.unlock();
}
}
} finally {
lock1.unlock();
}
}
锁排序
对多个锁进行全局排序,所有线程必须按固定顺序获取锁。例如通过System.identityHashCode()生成锁的优先级:
int fromHash = System.identityHashCode(lockA);
int toHash = System.identityHashCode(lockB);
if (fromHash < toHash) {
synchronized (lockA) {
synchronized (lockB) { /* ... */ }
}
} else if (fromHash > toHash) {
synchronized (lockB) {
synchronized (lockA) { /* ... */ }
}
}
减少锁粒度
将大锁拆分为多个小锁,降低锁竞争概率。例如ConcurrentHashMap通过分段锁提升并发度,替代对整个集合加锁。
死锁检测
通过线程转储分析死锁。使用jstack工具或ThreadMXBean编程检测:
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long[] threadIds = bean.findDeadlockedThreads();
if (threadIds != null) {
ThreadInfo[] infos = bean.getThreadInfo(threadIds);
for (ThreadInfo info : infos) {
System.out.println(info.getLockName());
}
}
使用无锁数据结构
考虑原子变量(AtomicInteger等)或并发容器(ConcurrentLinkedQueue),避免显式锁。CAS操作通过硬件指令实现线程安全,例如:

AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();
资源限时等待
对共享资源访问设置超时机制,如数据库连接池配置maxWait参数,防止线程无限期阻塞。






