死锁的讲解

目录

1. 死锁定义

2. 死锁产生原因

3. 如何解决死锁问题


1. 死锁定义

死锁是指两个或两个以上的进程在执⾏过程中,由于竞争资源或者由于彼此通信⽽造成的⼀种阻塞的现象,若⽆外⼒作⽤,它们都将⽆法推进下去。(也就是两个线程拥有锁的情况下,⼜在尝试获取对⽅锁,从⽽造成程序⼀直阻塞的情况。)

2. 死锁产生原因

形成死锁主要由以下 4 个因素造成的:         ① 互斥条件 ⼀个资源只能被⼀个线程占有,当这个资源被占⽤之后其他线程就只能等待。         ② 不可被剥夺条件 当⼀个线程不主动释放资源时,此资源⼀直被拥有线程占有,其他线程不能得到此资源。         ③ 请求并持有条件 线程已经拥有了⼀个资源之后,又尝试请求新的资源。         ④ 环路等待条件 产⽣死锁⼀定是发⽣了线程资源环形链。 形成死锁,四个因素缺一不可。

3. 如何解决死锁问题

打破产生死锁的一个或者多个条件即可。

        ① 互斥条件 改变不了。         ② 不可被剥夺条件 改变不了。         ③ 请求并持有条件 可以改变(人为控制)。         ④ 环路等待条件 可以改变(人为控制)。
public class UnDeadLock {public static void main(String[] args) {Object lockA = new Object();Object lockB = new Object();Thread t1 = new Thread(() -> {synchronized (lockA) {System.out.println("线程1:得到锁A");//业务代码try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lockB) {System.out.println("线程1:得到锁B");//业务代码System.out.println("线程1:释放锁B");}System.out.println("线程1:释放锁A");}},"线程1");t1.start();Thread t2 = new Thread(() -> {synchronized (lockB) {System.out.println("线程2:得到锁B");//业务代码try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lockA) {System.out.println("线程2:得到锁A");//业务代码System.out.println("线程2:释放锁A");}System.out.println("线程2:释放锁A");}},"线程2");t2.start();}
}输出线程1:得到锁A线程2:得到锁B
(......没有结束)

上面代码产生了死锁。解决方法:

1. 修改获取锁请求并持有条件:

解决死锁方法:破坏请求并持有条件public class UnDeadLock {public static void main(String[] args) {Object lockA = new Object();Object lockB = new Object();Thread t1 = new Thread(() -> {synchronized (lockA) {System.out.println("线程1:得到锁A");//业务代码try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}
//                synchronized (lockB) {
//                    System.out.println("线程1:得到锁B");
//                    //业务代码
//                    System.out.println("线程1:释放锁B");
//                }System.out.println("线程1:释放锁A");}},"线程1");t1.start();Thread t2 = new Thread(() -> {synchronized (lockB) {System.out.println("线程2:得到锁B");//业务代码try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}
//                synchronized (lockA) {
//                    System.out.println("线程2:得到锁A");
//                    //业务代码
//                    System.out.println("线程2:释放锁A");
//                }System.out.println("线程2:释放锁B");}},"线程2");t2.start();}
}输出:线程1:得到锁A线程2:得到锁B线程2:释放锁B线程1:释放锁A

 2. 修改获取锁的有序性来改变环路等待条件:

(使用顺序锁解决死锁问题)

 

 

解决死锁方法:修改获取锁的有序性来改变环路等待条件public class UnDeadLock2 {public static void main(String[] args) {Object lockA = new Object();Object lockB = new Object();Thread t1 = new Thread(() -> {synchronized (lockA) {System.out.println("线程1:得到锁A");//业务代码try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lockB) {System.out.println("线程1:得到锁B");//业务代码System.out.println("线程1:释放锁B");}System.out.println("线程1:释放锁A");}},"线程1");t1.start();Thread t2 = new Thread(() -> {synchronized (lockA) {System.out.println("线程2:得到锁A");//业务代码try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lockB) {System.out.println("线程2:得到锁B");//业务代码System.out.println("线程2:释放锁B");}System.out.println("线程2:释放锁A");}},"线程2");t2.start();}
}输出:线程1:得到锁A线程1:得到锁B线程1:释放锁B线程1:释放锁A线程2:得到锁A线程2:得到锁B线程2:释放锁B线程2:释放锁A


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部