【Java 死锁】用Java写个死锁

本文深入探讨了死锁的概念,分析其产生的四个必要条件,包括互斥、请求与保持、不剥夺及循环等待。文章提供了避免死锁的策略,如设置超时、共享锁、MySQL死锁恢复机制及银行家算法。并通过Java代码示例展示了死锁的产生过程。

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


死锁是什么

最简单的解释:两个人都想吃饭,但是只有一双筷子。A,B同时抢到了一只筷子,都想强一双,并且死不放手。结果就是A,B双双饿死。

因为资源有限,而想要资源的人过多,导致资源不足,互相争抢,最后产生了无穷尽的等待。

死锁不一定只会发生在锁的争抢上,从宏观上来讲,只要是有限的资源在使用时都可能发生死锁。这个概念最早是和操作系统中的PV原语同时出现,在操作系统中有一个著名的银行家算法可以绝对的避免死锁。

如:在使用redis,文件系统,mysql事务时都可能产生死锁。

死锁的必要条件

死锁发生了往往就会导致程序不可用,或者系统级别的崩溃。因此防范死锁是很重要的,但死锁也不是很容易就会发生的,它有如下四个必要条件。

  1. 互斥条件: 一个资源每次只能被一个进程使用; 即资源被A拿了,就不能再被B拿走;
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放; 即资源被A拿了,除非不用了,否则A不会归还。
  3. 不剥夺条件: 进程已获得的资源,在末使用完之前,不能强行剥夺; 即资源被A拿了,除非A归还,否则谁也抢不了。
  4. 循环等待条件: 若干进程之间形成一种头尾相接的循环等待资源关系; 即资源出现了不足的情况,且没人归还。每个人都没拿到足够多的资源,A祈祷B赶紧还了,B祈祷A,形成循环。

避免死锁有哪些方式

而如果要避免死锁的发生我们只需要破坏以上四个条件的其中之一即可。
如:
获取锁时设置超时时间(破坏条件2);
共享锁(破坏条件1);
MySQL死锁恢复机制(破坏条件3);
银行家算法(破坏条件4);

死锁的Java实现

下面是死锁发生的场景之一。
有两个线程A and B,A执行了一段任务想等B执行完成再执行,同样如果B如果执行了一半想等等A。那么就会一直等到天长地久QWQ。

    public static void main(String[] args)  {
        test2();
    }
    public static void test2(){
        class A{
            Thread threadA = null;
            Thread threadB = null;
            public void doSome(){
                threadA = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("A start");
                        try {
                            threadB.join();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("A end");
                    }
                });
                threadA = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("B start");
                        try {
                            threadA.join();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("B end");
                    }
                });
                threadA.start();
                threadB.start();
            }
        };
        new A().doSome();
    }

你会发现运行了Start 便没有了end。那么我们成功的写了一个死锁。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

梦鸢MoYuan

谢谢投喂!!!QWQ!!

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

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

打赏作者

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

抵扣说明:

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

余额充值