死锁
1. 死锁的产生
class MyThread implements Runnable {
static Object o1=new Object();
static Object o2=new Object();
private Boolean flag;
MyThread(Boolean flag){
this.flag=flag;
}
@Override
public void run() {
if(flag){
synchronized (o1){
System.out.println(Thread.currentThread().getName()+"持有o1");
synchronized (o2){
System.out.println(Thread.currentThread().getName()+"持有o2");
}
}
}else{
synchronized (o2){
System.out.println(Thread.currentThread().getName()+"持有o2");
synchronized (o1){
System.out.println(Thread.currentThread().getName()+"持有o1");
}
}
}
}
}
public class DeadLock {
public static void main(String[] args) throws InterruptedException {
new Thread(new MyThread(Boolean.TRUE),"t1").start();
new Thread(new MyThread(Boolean.FALSE),"t2").start();
}
}
2. 死锁的排查
2.1 拿到进程号jps -l
2.2 jstack 10996
3. 预防死锁
3.1 一次性申请所有的资源
3.2 以确定的顺序获得锁(靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。)
3.3 超时放弃(占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源)
当使用synchronized关键词提供的内置锁时,只要线程没有获得锁,那么就会永远等待下去,然而Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方法可以按照固定时长等待锁,因此线程可以在获取锁超时以后,主动释放之前已经获得的所有的锁。通过这种方式,也可以很有效地避免死锁。
锁demo:https://www.bilibili.com/video/BV1zB4y1A7rb?p=17&vd_source=b901ef0e9ed712b24882863596eab0ca
死锁解决方案:https://blog.csdn.net/hd12370/article/details/82814348?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-82814348-blog-124705063.pc_relevant_multi_platform_featuressortv2dupreplace&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-82814348-blog-124705063.pc_relevant_multi_platform_featuressortv2dupreplace&utm_relevant_index=5
死锁解决方案:https://javaguide.cn/java/concurrent/java-concurrent-questions-01.html#%E5%A6%82%E4%BD%95%E9%A2%84%E9%98%B2%E5%92%8C%E9%81%BF%E5%85%8D%E7%BA%BF%E7%A8%8B%E6%AD%BB%E9%94%81