死锁的认识


一.死锁的三个典型情况

1.一个线程对同一对象连续加锁两次,如果锁是不可重入的就会造成死锁
什么是可重入锁 点击

2.两个线程两把锁,t1和t2各自先针对锁A和锁B加锁,再互相获取对方的锁

例子:线程 t1 先请求对 apple 加锁,t2 对 banana 加锁,之后 t1 线程在持有apple的情况请求对 banana 加锁,t2线程在持有 banana 的情况请求对 apple 加锁,造成两个线程互相等待。

	public class demo2 {
    public static void main(String[] args) {
        Object apple = new Object();
        Object banana = new Object();
        Thread t1 = new Thread(()->{
           synchronized (apple){
               try {
                   Thread.sleep(1000); //加 sleep 为了确保让两个线程把第一把锁拿到,否则不容易构建出这个情况因为线程抢占式执行的
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               synchronized (banana){
                   System.out.println("t1拿到苹果和香蕉了");
               }
           }
        },"t1");
        Thread t2 = new Thread(()->{
            synchronized (banana){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (apple){
                    System.out.println("t2拿到苹果和香蕉了");
                }
            }
        },"t2");
        t1.start();
        t2.start();
    }
}

程序输出为空:
结果

通过 jconsole 工具查看线程情况:
t1:
t1
t2:
t2


3.多个线程多把锁
例子:哲学家就餐问题
如下图每两个人之间有一只筷子,每个人只能拿左右手边的筷子,只有拿够两只筷子才能吃饭。
如果出现极端情况每个人都拿了一只,就会使所有人不能吃饭互相等待,造成死锁。
哲学家就餐


二.死锁产生的四个必要条件

互斥使用 :对同一个对象上锁,多个线程中只有一个能成功,其他线程阻塞
不可强占:一但一个线程拿到锁,其他线程只能等其释放,不能抢
请求和保持 :一个线程拿到锁A,在没有释放锁A的基础上请求获取锁B。
循环等待:两个线程两把锁,t1和t2各自先针对锁A和锁B加锁,再互相获取对方的锁


三.如何破除死锁

只需让死锁产生的四个条件有一个不满足即可,前三个是锁的特性,以前OS就是这样设计的,对于synchronized 前三个条件修改不了。从第四个条件入手:如采用给锁编号,指定加锁顺序的方法

如上例,当我们给锁对象(筷子)编号,指定加锁顺序(这里采用从小到大的顺序):
下图,AE会争抢1号筷子,其他三人都去拿其右手边筷子。如果E拿到1,E会和D有一个成功拿到5,其它四人陷入阻塞,成功的人就餐结束后释放锁(筷子),最后每个人都能吃到饭;同理如果A拿到1后,D会再拿到5先吃到饭(E会阻塞因为拿锁顺序是从小到大只能拿1),最后每个人都能吃到饭。
a

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值