因为热爱所以坚持,因为热爱所以等待。熬过漫长无戏可演的日子,终于换来了人生的春天,共勉!!!
1.什么是死锁?
①死锁:指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。
②原因:
- 系统资源不足
- 进程运行推进的顺序不合适
- 资源分配不当
③示意图:
为了更好看清什么是死锁,我们通过代码来写一个死锁
2.编写一个死锁
流程:
- ①编写资源类
- ②线程取得自己的锁,同时想去获取别人的锁(吃着碗里的,看着锅里的)
- ③创建两个线程执行
代码:
package JUC;
import java.util.concurrent.TimeUnit;
class HoldLockThread implements Runnable {
private String lock1;
private String lock2;
public HoldLockThread(String lock1, String lock2) {
super();
this.lock1 = lock1;
this.lock2 = lock2;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (lock1) {
System.out.println(Thread.currentThread().getName()+"\t 自己持有:"+lock1+"\t 尝试获取: " + lock2);
try {TimeUnit.SECONDS.sleep(2);} catch (Exception e) {e.printStackTrace();}
synchronized (lock2) {
System.out.println(Thread.currentThread().getName()+"\t 自己持有:"+lock2+"\t 尝试获取: " + lock1);
}
}
}
}
public class DeathLockDemo {
public static void main(String[] args) {
String lockA= "lockA";
String lockB= "lockB";
new Thread(new HoldLockThread(lockA,lockB),"ThreadA").start();
new Thread(new HoldLockThread(lockB,lockA),"ThreadB").start();
}
}
执行结果:程序一直运行
ThreadA 自己持有:lockA 尝试获取: lockB
ThreadB 自己持有:lockB 尝试获取: lockA
3.如何排查
①jps -l 查找java进程
C:\Users\ASUS>jps -l
13460 jdk.jcmd/sun.tools.jps.Jps
9716 C:\Users\ASUS\Desktop\JAva\eclipse\\plugins/org.eclipse.equinox.launcher_1.5.400.v20190515-0925.jar
17256 JUC.DeathLockDemo
找到我们直接写的类的进程号
②jstack 找到死锁查看相关信息
C:\Users\ASUS>jstack 17256
2021-10-02 18:00:52
Full thread dump Java HotSpot(TM) 64-Bit Server VM (11.0.8+10-LTS mixed mode):
//省略部分信息
Found one Java-level deadlock:
=============================
"ThreadA":
waiting to lock monitor 0x00000232780e2080 (object 0x0000000089a5deb8, a java.lang.String),
which is held by "ThreadB"
"ThreadB":
waiting to lock monitor 0x00000232780e1c80 (object 0x0000000089a5de88, a java.lang.String),
which is held by "ThreadA"
Java stack information for the threads listed above:
===================================================
"ThreadA":
at JUC.HoldLockThread.run(DeathLockDemo.java:22)
- waiting to lock <0x0000000089a5deb8> (a java.lang.String)
- locked <0x0000000089a5de88> (a java.lang.String)
at java.lang.Thread.run([email protected]/Thread.java:834)
"ThreadB":
at JUC.HoldLockThread.run(DeathLockDemo.java:22)
- waiting to lock <0x0000000089a5de88> (a java.lang.String)
- locked <0x0000000089a5deb8> (a java.lang.String)
at java.lang.Thread.run([email protected]/Thread.java:834)
Found 1 deadlock.
③定位死锁的位置
通过对jstack输出信息的分析,我们可以看出死锁产生的具体位置以及原因,完美解决!!!
我之前写过一篇关于JVM排查命令的文章,里面详细介绍了这些指令,感兴趣的小伙伴可以去看一看:深入理解Java虚拟机系列 --13 性能监控与调优篇 --01JVM命令行监控工具因为热爱所以坚持,因为热爱所以等待。熬过漫长无戏可演的日子,终于换来了人生的春天,共勉!!!1.性能指标①.停顿时间(或响应时间)②.吞吐量③.并发数④.内存占用⑤.相互间的关系下一篇 14 性能监控与调优篇02参考视频 :尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机)参考书籍 : 深入理解Java虚拟机...https://blog.csdn.net/qq_43295483/article/details/120382134?spm=1001.2014.3001.5501