用一个生动而形象的例子描述死锁的必要条件之不好意思, 我要扳手, 不要班花

news/2024/5/20 11:58:19 标签: java, 开发语言, Thread, 多线程, 死锁

不好意思, 我要扳手, 不要班花 🛩️

    • 死锁的必要条件
    • 生动而形象的例子
    • Java 中的死锁示例

死锁的必要条件

判断死锁的必要条件通常包括以下几点:

  1. 互斥条件:资源只能被一个进程(或线程)占有,无法被其他进程共享。
  2. 请求与保持条件:一个进程在请求新资源的同时,保持对已分配资源的占有。
  3. 不可剥夺条件:资源不能被强制从占有者手中回收,只能由占有者自愿释放。
  4. 循环等待条件:存在一个进程(或线程)等待序列,其中每个进程都在等待下一个进程释放资源。

生动而形象的例子

现在桌上摆着一把锤子, 一把扳手 // 互斥条件

我拿到了左手拿到一把锤子, 这时我准备去拿扳手 // 请求与保持条件

可这时我发现扳手被拿去开啤酒了, 而且他还想拿我的锤子开核桃

我不打算放弃, 你这拿去开啤酒开核桃明显不合理, // 不可剥夺条件,除非打架

我可是打算拿着锤子跟扳手去跟隔壁班花约会的

于是为了跟班花完美的约会, 于是我在这里等扳手

两个人一直耗到海枯石烂, 隔壁班花也有了自己的孩子 // 循环等待条件

于是你感慨死锁真是害人呀, 不说了, 继续等扳手了

Java 中的死锁示例

java">public class DeadlockExample {

    public static void main(String[] args) {
        final Object lock1 = new Object();
        final Object lock2 = new Object();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock1) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (lock2) {
                        System.out.println("Thread 1 is holding lock 1 and lock 2.");
                    }
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock2) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (lock1) {
                        System.out.println("Thread 2 is holding lock 1 and lock 2.");
                    }
                }
            }
        });

        t1.start();
        t2.start();
    }
}

在上述代码中,有两个线程 t1 和 t2,它们同时试图获取 lock1 和 lock2 两个对象的锁,但获取锁的顺序不同。假设 t1 先获取了 lock1 的锁,然后在试图获取 lock2 的锁时被阻塞,而此时 t2 已经获取了 lock2 的锁,并试图获取 lock1 的锁,但 lock1 的锁已经被 t1 占用,因此 t2 也会被阻塞。这时候就产生了死锁,t1 和 t2 互相等待对方释放锁,导致程序无法继续执行。


http://www.niftyadmin.cn/n/193792.html

相关文章

【创作赢红包】循序渐进的全版本通讯录详解,可保存信息的动态通讯录

之前的博客里我们实现了静态的通讯录。|ू・ω・ ) 静态通讯录,适合初学者的手把手一条龙讲解_陈大大陈的博客-CSDN博客 这个版本的通讯录无法实现容量的动态增加,也无法保存我们输入的信息。(•́へ•́╬) 静态通讯录&#xff…

ESP32设备驱动-MLX90615红外测温仪驱动

MLX90615红外测温仪驱动 1、MLX90615介绍 MLX90615 是一款用于非接触式温度测量的微型红外温度计。 IR 敏感热电堆探测器芯片和信号调节 ASIC 都集成在同一个微型 TO-46 罐中。 红外测温仪出厂时经过数字 SMBus 输出校准,可在完整温度范围内以 0.02 C 的分辨率完全访问测量温…

面向对象编程(基础)1:面向对象思想精髓的理解

目录 1. 面向对象编程概述(了解) 1.1 程序设计的思路 1. 面向过程的程序设计思想(Process-Oriented Programming),简称POP 2. 面向对象的程序设计思想( Object Oriented Programming),简称OOP 1.2 由实…

Java多线程:ReentrantLock的使用和Condition

ReentrantLock ReentrantLock,一个可重入的互斥锁,它具有与使用synchronized方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。 ReentrantLock基本用法 先来看一下ReentrantLock的基本用法: public class…

rk3568 Android 添加IR遥控器

rk3568 添加IR遥控器 生活中充满了各种波长的电磁波,所谓的可见(色)光就是人眼可见的电磁波谱,其波长为 380~770nm,为了避免遥控器发射的光造成人眼不适及减少一般人造光源干扰,故选用人眼不可见的红外线(Infrared)波长&#xff…

HashMap底层数据结构

TreeMap TreeMap的底层是红黑树,是自平衡的二叉查找树。 在查找元素时会从左子树或右子树查找,和元素一个一个进行比较,对于大数量的查找的场景TreeMap不适合(HashMap解决了这个问题)。 TreeMap的好处,是…

动态规划-子序列问题(最长递增子序列、最长连续递增序列。最长重复子数组。最长公共子序列、不相交的线、最大子数组和)

文章目录1. 最长递增子序列思路:代码:2. 最长连续递增序列思路:代码:3. 最长重复子数组思路:代码:4. 最长公共子序列思路:代码:5. 不相交的线思路:代码:6. 最…

【MySQL--01】数据库基础

文章目录1.什么是数据库2.主流数据库2.1 MySQLMySQL架构实例3.基本使用3.1 MySQL的安装3.2 连接服务器3.3服务器管理4.服务器,数据库,表之间的关系5.使用数据库6.SQL分类7.存储引擎查看存储引擎存储引擎对比1.什么是数据库 数据库是用来存储数据的。那么…