目录
首先简单的顺序死锁代码
执行之后线程机会发生死锁
/**
* 测试简单顺序死锁
**/
public class TestDeadLock {
static class CustomerA extends Thread{
Object a;
Object b;
public CustomerA(Object a, Object b) {
this.a = a;
this.b = b;
}
@Override
public void run() {
synchronized (a){
try {
System.out.println("CustomerA开始执行,获取了锁a");
Thread.sleep(100);
synchronized (b){
System.out.println("CustomerA执行完成");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class CustomerB extends Thread{
Object a;
Object b;
public CustomerB(Object a, Object b) {
this.a = a;
this.b = b;
}
@Override
public void run() {
synchronized (b){
try {
System.out.println("CustomerB开始执行,获取了锁b");
Thread.sleep(100);
synchronized (a){
System.out.println("CustomerB执行完成");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
new CustomerA(a,b).start();
new CustomerB(a,b).start();
}
}
使用jps查看发生死锁的应用的id
jps备注:
jps类似linux系统中的ps,应为java使用所以前面加上了j,即jps-->java+ps,这样就能更好的理解了,我刚开始就只想到jps是JVM的工具,没想到就是java+ps
使用
在jdk安装目录的/bin目录下面执行cmd,(不能直接双击运行jps.exe)
执行 jsp -l
D:\install\jdk8\bin>jps -l
18132
13080 org.jetbrains.jps.cmdline.Launcher
25240 cn.enjoyedu.ch7.safeclass.TestDeadLock
1276 sun.tools.jps.Jps
15788 org.jetbrains.idea.maven.server.RemoteMavenServer
可以看到执行对象TestDeadLock的应用id是25240
通过jstack id 查看应用的锁的持有情况
jstack简单介绍:(Stack Trace for java),用于查看每一条贤臣给正在执行的方法堆栈的集合,从而定位线程出现长时间停顿的原因
执行: jstack -l 25240
会发现打印:Found one Java-level deadlock:,说明出现了死锁
而Java stack information for the threads listed above:会打印出发生死锁的线程,这样就定位到了发生死锁的线程和位置
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x000000000293eea8 (object 0x0000000740ba92a8, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x000000000293da08 (object 0x0000000740ba92b8, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at cn.enjoyedu.ch7.safeclass.TestDeadLock$CustomerB.run(TestDeadLock.java:47)
- waiting to lock <0x0000000740ba92a8> (a java.lang.Object)
- locked <0x0000000740ba92b8> (a java.lang.Object)
"Thread-0":
at cn.enjoyedu.ch7.safeclass.TestDeadLock$CustomerA.run(TestDeadLock.java:23)
- waiting to lock <0x0000000740ba92b8> (a java.lang.Object)
- locked <0x0000000740ba92a8> (a java.lang.Object)
Found 1 deadlock.
解决死锁方法
1、确定线程拿锁的顺序
2、采用尝试哪所的方式(Lock的tryLock()方法)
详细可以参考:产生死锁的四个必要条件、解决死锁的常用方式(有序资源法和银行家算法)