Java 死锁的个人尝试和理解

本文通过一个简单的Java死锁例子,展示了如何利用jstack命令来检测和分析死锁情况。线程类1未出现死锁,而线程类2因等待资源引发死锁,导致程序无法继续执行。通过jstack的输出,可以清晰看到两个线程互相持有对方所需的监视器锁,形成死锁状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

死锁的例子是参考网上的例子,主要是想学习一下jstack命令来识别死锁。

package basic;


import smallbird.Tools;


public class DeadThreadExample {


public static void main(String[] args) {
Thread1 t1=new Thread1();
Thread1 t2=new Thread1();
t1.mark=0;
t2.mark=1;
t1.start();
t2.start();
DeadLockThread r1=new DeadLockThread();
r1.setMark(0);
DeadLockThread r2=new DeadLockThread();
r2.setMark(1);
new Thread(r1).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("sleep 10ms error");
};
new Thread(r2).start();
}
}

// 线程1

class Thread1 extends Thread{


int mark;

static Object obj1=new Object(),obj2=new Object();

@Override
public void run() {
if (mark==0) {
synchronized(obj1) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("object obj1 sleep error."+Tools.getNowDate(null));
}
}
synchronized(obj2) {
System.out.println("obj2 mark:"+mark+". "+Tools.getNowDate(null));
}
} else if (mark==1) {
synchronized(obj2) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("object obj2 sleep error."+Tools.getNowDate(null));
}
}
synchronized(obj1) {
System.out.println("obj1 mark:"+mark+". "+Tools.getNowDate(null));
}
}
System.out.println("End Thread: "+this.getName()+"."+Tools.getNowDate(null));
}
}

// 线程2
class DeadLockThread implements Runnable{


int mark;

static Object obj1=new Object(),obj2=new Object();

@Override
public void run() {
if (mark==0) {
synchronized(obj1) {
try {
Thread.sleep(1000*180);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("object obj1 sleep error."+Tools.getNowDate(null));
}
synchronized(obj2) {
System.out.println("obj2 mark:"+mark+". "+Tools.getNowDate(null));
}
}

} else if (mark==1) {
synchronized(obj2) {
System.out.println("obj1 mark:"+mark+". "+Tools.getNowDate(null));
synchronized(obj1) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("object obj2 sleep error."+Tools.getNowDate(null));
}

}
}
}
System.out.println("End ."+Tools.getNowDate(null));
}


public int getMark() {
return mark;
}


public void setMark(int mark) {
this.mark = mark;
}

}

使用Eclipse开发,Run后,在任务管理器找到pid,可以执行两次,pid没有变化的估计是Eclipse进程用到的,另一个javaw.exe就是我们Run的进程。

cmd命令窗口,jstack -l  3616

输出截图:





主要看第3张截图,发现了死锁。

线程类1没有出现死锁,线程类2出现了死锁。我电脑是i3处理器,所以线程类1执行很快,没有遇到死锁。

控制台打印:

obj1 mark:1. 2015-06-24 21:26:58,051
obj2 mark:0. 2015-06-24 21:26:58,503
End Thread: Thread-0.2015-06-24 21:26:58,503
obj1 mark:1. 2015-06-24 21:26:58,503
End Thread: Thread-1.2015-06-24 21:26:58,503

这个是已经等了有差不多10分钟左右,还没有执行完成。关键是线程类2中等待了3分钟时间,这个导致多核CPU也不能快速执行完。

Found one Java-level deadlock:
=============================
"Thread-3":
  waiting to lock monitor 0x000000000052a8f0 (object 0x00000000f00f1d70, a java.
lang.Object),
  which is held by "Thread-2"
"Thread-2":
  waiting to lock monitor 0x000000000052a998 (object 0x00000000f00f1d80, a java.
lang.Object),
  which is held by "Thread-3"


Java stack information for the threads listed above:
===================================================
"Thread-3":
        at basic.DeadLockThread.run(DeadThreadExample.java:92)
        - waiting to lock <0x00000000f00f1d70> (a java.lang.Object)
        - locked <0x00000000f00f1d80> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:662)
"Thread-2":
        at basic.DeadLockThread.run(DeadThreadExample.java:83)
        - waiting to lock <0x00000000f00f1d80> (a java.lang.Object)
        - locked <0x00000000f00f1d70> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:662)


Found 1 deadlock.



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值