死锁以及如何解决死锁
转自https://www.cnblogs.com/aflyun/p/9194104.html,真的很详细。包括我之前总结的cpu100%如何解决也有。
死锁4大要素:互斥,持有并请求,不可剥夺,持续等待
那么如何避免死锁?破坏其中一个条件
说是这么说,代码撸起来。写一个死锁:
public class TheBackLock {
public static String object1 = "obj1";
public static String object2 = "obj2";
public static void main(String[] args) {
Thread thread = new Thread(new MyThread(false));
Thread thread1 = new Thread(new MyThread(true));
thread.start();
thread1.start();
}
}
class MyThread implements Runnable {
private boolean flag;
public MyThread(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
if (flag) {
try {
while (true) {
synchronized (TheBackLock.object1) {
System.out.println(Thread.currentThread().getName() + "lock object1");
Thread.sleep(3000);
synchronized (TheBackLock.object2) {
System.out.println(Thread.currentThread().getName() + "lock object2");
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
while (true) {
synchronized (TheBackLock.object2) {
System.out.println(Thread.currentThread().getName() + "lock object2");
Thread.sleep(3000);
synchronized (TheBackLock.object1) {
System.out.println(Thread.currentThread().getName() + "lock object1");
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这例子分析下如何死锁了,第一个互斥条件,有两个线程,我们命名为a,b吧。a获取object1锁,synchronized是由jvm进行管理的锁,Thread.sleep(3000)是为了让b有获取object2锁的充足时间。那么3秒过后,a去尝试获取object2锁的时候,这时就互斥了。第二持有并请求,a有了object1锁,再请求object2锁的时候才会死锁。第三不可剥夺 ,synchronized不像Lock类,扩展性强。第四持续等待,看到while(true)了没有
如何解决死锁
1.调用jps -l
输出完全的包名,应用主类名,jar的完全路径名
jstack -l pid
查看堆栈信息
jmap也可以dump下来堆栈的信息查看
deadlock有没有
2.使用jdk->bin下面Visual VM
监控很到位,虽然我不是很会用
3.cpu100%我之前博客说过
https://blog.****.net/weixin_38336658/article/details/81437022
总结:不外乎找到占用的pid,转tid,jstack pid,或者jmap dump出来,查看对应哪里报错