死锁===

本文详细解释了死锁的概念,探讨了线程对锁的加锁行为可能导致死锁的情况,包括不可重入锁和可重入锁的区别,以及经典的哲学家吃面问题。文章还介绍了死锁的必要条件和避免死锁的方法,如银行家算法和加锁顺序的规定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

死锁

1.有一个线程,针对同一把锁,连续加锁两次,如果产生了锁死,就是不可重入锁

public static synchronized void increase()//锁加锁加到静态方法上就是对类对象加锁,其他的都是加载到this上
{
    synchronized(this)
    {

    }
}

上述代码1.调用方法,先针对this加锁,此时假设加锁成功了2.接下来往下执行,代码块中也加了一个锁,此时针对方法的锁还没有释放,代码块中的就不会得到,此时就会产生锁竞争。如果是一个不可重入锁,这把锁不会保存,是哪一个线程对他加锁,只要它当前处于加锁状态,收到了“加锁”的请求,就会当即拒绝这个请求,而不管当下是那个线程,都会产生死锁,而可重入锁,则会让这个所保存起来,是哪个线程加上锁,后续收到加锁请求就会先对比一下,看看枷锁线程是不是当前持有这把锁,这个时候就可以了灵活判断了(synchronized本身是一个可重入锁),若加锁很多个,那就是在最外面的那个锁解开,(增加一个计数器,遇到加锁+1,解锁-1,在零处释放)。

2.两个线程,两把锁,这两个线程分别获取到一把锁,然后尝试获取对方的锁。

public class dome1 {
    public static Object locker1=new Object();
    public static Object locker2=new Object();
    public static void main(String[] args) {
        Thread t1=new Thread(()->{
            synchronized (locker1)
            {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (locker2) {
                    System.out.println("t1");
                }
            }
        });
        Thread t2=new Thread(()->{
            synchronized (locker2)
            {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (locker1) {
                    System.out.println("t2");
                }
            }
        });
        t1.start();
        t2.start();
    }
}

3.N个线程M个锁

 典型问题:哲学家吃面问题

问:1.哲学家思考人生的时候会放下筷子2.吃面时,会拿起左手和右手的筷子,再去加面条吃

条件:1.每个哲学家,啥时候思考人生,啥时候吃面条是不确定的;2.每个哲学家都很固执,如果他的筷子每人使用了,他就会出发阻塞,等到别人放下筷子

当五个哲学家都想吃面,就会出现死锁。

 

如何避免死锁

1.先要明确死锁的必要条件:

1)互斥使用,一个线程获得一个锁后,别的线程就不能获得。

2)不可抢占:锁只有是被持有者释放才能有别的线程会得到锁

3)请求和保持:这一个线程去尝试获取多把锁,在获取第二把锁的时候,会保持对第一把所得获取状态;

4)循环等待:t1尝试获取locker2,需要先执行完t2,t2尝试获取locker1,需要先执行完t1;

2.可以发现四个条件时同时满足才可发生死锁,所以只要破坏一个即可打破死锁。最有可能打破四

3.解决办法

1)银行家算法-》较为麻烦

2)针对锁编号,规定加锁的顺序严格遵守,比如规定,每个线程如果要获取多把锁,就必须先获取编号小的锁,后获取编号打的锁,

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

圆圆无敌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值