死锁形成的4个必要条件与哲学家就餐问题

什么是死锁

多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线
程被无限期地阻塞,因此程序不可能正常终止

死锁的4个必要条件

互斥使用: 当一个资源被一个线程占用时,另一个线程不可以使用

不可抢占: 资源请求者不可以从资源持有者手中去抢夺资源,只可以等待资源持有者来进行主动释放

请求和保持: 资源请求者在请求一个资源时,同时保持对一个资源的占有

循环等待: P1占有P2所需要的资源,P2占有P3所需要的资源,P3占有P1所需要的资源,形成了一个等待环路

所以如果我们想要避免死锁就只需要打破上述4个必要条件中的一种。就可以来有效避免。其中条件“循环等待”就是我们最好下手的条件(破坏循环等待)

哲学家就餐问题

每个 哲学家 只做两件事: 思考人生 或者 吃面条. 思考人生的时候就会放下筷子. 吃面条就会拿起左
右两边的筷子(先拿起左边, 再拿起右边)
 

 当4号哲学家正在吃面时,哲学家3号就会等带哲学家4号(进入阻塞等待),等到哲学家4号吃完,放下筷子后就会拿起筷子吃面

 一般情况下会正常进行,但假设同一时刻, 五个 哲学家 同时拿起左手边的筷子, 然后再尝试拿右手的筷子, 就会发现右手的筷子都被占用了. 由于 哲学家 们互不相让, 这个时候就形成了死锁

 解决方法如下

 代码演示如下:

当没有进行约定时

    public static void main(String[] args) {
        Object locker1 = new Object();
        Object locker2 = new Object();

        Thread t1 = new Thread(() -> {
            synchronized (locker1){
                synchronized (locker2){
                    //do something
                }
            }

        });

        t1.start();

        Thread t2 = new Thread(() -> {
            synchronized (locker2){
                synchronized (locker1){
                    //do something
                }
            }
        });

        t2.start();
    }

约定好先获取 lock1, 再获取 lock2 , 就不会环路等待
 

    public static void main(String[] args) {
        Object locker1 = new Object();
        Object locker2 = new Object();

        Thread t1 = new Thread(() -> {
            synchronized (locker1){
                synchronized (locker2){
                    //do something
                }
            }

        });

        t1.start();

        Thread t2 = new Thread(() -> {
            synchronized (locker1){
                synchronized (locker2){
                    //do something
                }
            }
        });

        t2.start();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值