口诀:"吃着碗里.看着锅里"
package com.dj.springbootdemo.demo;
/**
* User: ldj
* Date: 2023/6/4
* Time: 12:05
* Description: No Description
*/
public class DeadLock {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
doWork(obj1, obj2);
doWork(obj2, obj1);
}
//吃着碗里,看着锅炉里 (嵌套sync)
private static void doWork(Object p, Object q) {
new Thread(() -> {
synchronized (p) {
//没有业务代码,不会出现死锁
//System.out.println(p);
synchronized (q) {
System.out.println(q);
}
}
}).start();
}
}
package com.dj.springbootdemo.demo;
/**
* User: ldj
* Date: 2023/6/4
* Time: 12:05
* Description: No Description
*/
public class DeadLock {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
doWork(obj1, obj2);
doWork(obj2, obj1);
}
//吃着碗里,看着锅炉里
private static void doWork(Object p, Object q) {
new Thread(() -> {
synchronized (p) {
System.out.println(p);
synchronized (q) {
//System.out.println(q);
}
}
}).start();
}
}
核心:
package com.dj.springbootdemo.demo;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* User: ldj
* Date: 2023/6/4
* Time: 12:05
* Description: No Description
*/
public class DeadLock {
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
//doWork(obj1, obj2);
//doWork(obj2, obj1);
doWork2(obj1, obj2);
doWork2(obj2, obj1);
}
//吃着碗里,看着锅炉里,会出现死锁
private static void doWork(Object p, Object q) {
new Thread(() -> {
synchronized (p) {
System.out.println(p);
synchronized (q) {
System.out.println(q);
}
}
}).start();
}
//把需要的全部资源放到公共的地方,然后全部锁起来,使用的时候一次申请所有资源,用完全部释放,就不会造成死锁
private static void doWork2(Object p, Object q) {
new Thread(() -> {
List<Object> resources = new ArrayList<>();
resources.add(p);
resources.add(q);
boolean flag = true;
while (flag) {
//申请资源
boolean access = ResourceManager.applyResources(resources);
if (access) {
//关闭循环
flag = false;
try {
System.out.println(Thread.currentThread().getName() + "=========p和q都拿到了");
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("释放资源");
ResourceManager.releaseResources(resources);
}
}
}
}).start();
}
}
class ResourceManager {
public static List<Object> objectBucket = new ArrayList<>();
public static synchronized boolean applyResources(List<Object> resources) {
if (objectBucket.size() > 0) {
return false;
} else {
objectBucket.addAll(resources);
}
return true;
}
public static void releaseResources(List<Object> resources) {
if (objectBucket.size() > 0) {
objectBucket.clear();
}
}
}
第二部分:死锁排查
# 查看进程号
jps -l
# 查看堆信息
jstack 进程号
或者借助可视化工具 jconsole