死锁的情况和避免方法

在多线程并发中,就会遇到死锁的情况。
死锁的一个定义就是:一组互相竞争资源的线程因互相等待,导致永久阻塞的现象。
比如一组操作需要同时获取两个锁1,2,线程a线程获取锁1的同时,线程b同时获取锁2,那么线程1,2同时去获取对方的锁,而双方本身都又在等待多方的锁,那么就陷入一个无限的死循环中,导致死锁。

只有以下情况都发生时才会出现死锁:
1.互斥,共享资源X和Y只能被一个线程占用。
2.占用且等待,线程T1已经获得共享资源X,在等待共享资源Y的时候,不释放共享资源X;
3.不可抢占,其他线程不能强行抢占线程T1占有的资源。
4.循环等待,线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源,就是循环等待。

那么解决问题的方法就在于破坏线程死锁的条件,导致影响线程死锁的条件不成立即可。
1.破坏占用且等待的条件。即只要一个线程需要获取2个锁时才能进行的操作,那么我们只要建立一个对象,对象去同时获取2个锁,再来个方法同时释放2个锁。这样任意线程去获取的时候,要么都拿到锁进行操作,其余没拿到锁的线程就进行等待。

2.破坏不可抢占的条件。主动释放资源,即如果当前线程获取不到全部的锁,那么主动释放自身拥有的锁,等待全部获得锁的机会。

3.破坏循环等待条件。 要想破坏这个条件,必须对资源进行排序,然后按序申请资源。根据获取的Id比较大小,按照从小到大顺序来申请锁,这样就不会存在循环等待的条件了。这样有点乐观锁的感觉。 为啥这样做能解决循环等待问题。因为当2个线程去获取锁,按照从小到大的情况排序去获取锁,那么大于等于2个线程去获取,只会其中一个线程拿到最小的锁,才能去拿第二锁,如果连第一个锁都拿不到,自然其他线程就不能进入第二个锁的获取代码部分。于是便解决了循环等待问题。

总结:当加锁的时候,就要想到避免死锁的情况。考虑最好的解决方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值