线程中的死锁详解

it2025-09-14  4

死锁

死锁的由来定位方法避免死锁

死锁的由来

在多线程场景中,多个线程互相持有对方需要的锁,从而造成了阻塞。严重影响了性能。

常见的死锁:顺序死锁,动态死锁(转账)


//顺序死锁的示例代码。 public class Test { public static void main(String[] args) { //两个对象锁 Object a1=new Object(); Object a2=new Object(); //创建两个线程 A t1=new A(a1,a2); B t2=new B(a1,a2); t1.setName("t1"); t2.setName("t2"); t1.start();t2.start(); } } class A extends Thread{//一个类里两个对象 Object o1; Object o2; public A(Object o1, Object o2) { this.o1 = o1; this.o2 = o2; } public void run(){ //死锁 //t1进来,先锁o1,在锁o2 synchronized (o1){ System.out.println("线程t1占用了o1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (o2){ System.out.println("线程t1占用了o2"); } } } } class B extends Thread{//一个类里有两个对象。 Object o1; Object o2; public B(Object o1, Object o2) { this.o1 = o1; this.o2 = o2; } public void run(){ //t2进来,先锁o2,在锁o1 synchronized (o2){ System.out.println("线程t2占用了o2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (o1){ System.out.println("线程t2占用了o1"); } } }

线程A占用o1锁,想要占用o2锁。线程B占用o2锁,想要占用o1锁。

问题:线程B没有释放o2锁那么线程A就无法完成。线程A没有释放o1锁,线程B也没有办法完成。就这样造成了死锁。


定位方法

通过jstack分析线程的栈信息; 或者使用ThreadMXBean相关的api在程序中打印出相关的死锁信息;


避免死锁

一、尽量不要嵌套锁。 二、如果要使用嵌套锁,注意顺序关系。 三、对代码进行审查,提前发现然后修正代码。

最新回复(0)