当前位置: 首页 > article >正文

浅谈死锁以及判断死锁的方法

引言

我们在并发情况下见过很多种锁,synchronized,ReentrantLock 等等,这些锁是为了保证线程安全,使线程同步的锁,与今天所要学习的死锁并不相同,死锁并不是一种锁,而是一种现象。

官方定义:死锁就是在两个或两个以上线程都想获得对方所持有的资源,从而相互等待的这么一种状态。

*************************************************举个栗子*************************************************

你正在面试,面试官让你给他讲一讲什么是死锁,然后你告诉面试官:“你给我发 offer 我就讲讲什么是死锁。”面试官说:“你给我讲讲死锁,我就给你发 offer。”这就进入了互相等待的状态,面试官想获得你对死锁的理解,你又想获得面试官的 offer 这就是两个线程都想获得对方所持有的资源,从而互相等待。

代码示例

程序中有两个线程

线程 t1 需要先获得锁 lockA 再获得锁 lockB

线程 t2 需要先获得锁 lockB 再获得锁 lockA

我们可以预料的是,当 t1,t2 线程启动之后,t1 线程获得了 lockA,t2 线程获得了 lockB,这时候 t1 线程再想获得 lockB 就会进入到 blocked 状态,t2 线程想获得 lockA 也会进入到 blocked 状态,这样两个线程就会互相等待,造成死锁。

public class Demo01 {
    public static void main(String[] args) {
        DeadLock deadLock = new DeadLock();
        Thread t1 = new Thread(() -> {
            try {
                deadLock.add();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, "t1线程");
        Thread t2 = new Thread(() -> {
            deadLock.dec();
        }, "t2线程");
        t1.start();
        t2.start();
    }
}

class DeadLock {
    private final Object lockA = new Object();
    private final Object lockB = new Object();

    public void add() throws InterruptedException {
        synchronized (lockA) {  // 获取lockA
            /**
             * 线程休眠
             * 为了让其他线程尽快获得lockB
             * 否则当前线程执行太快会得到lockA,lockB就不会死锁
             */
            Thread.sleep(1000);
            synchronized (lockB) { // 又获取到了lockB
                System.out.println("add()");
            }
        }
    }

    public void dec() {
        synchronized (lockB) {
            synchronized (lockA) {
                System.out.println("dec()");
            }
        }
    }
}

判断死锁

程序出现死锁之后就会,进入等待状态,不会向下运行,那么难道只要程序出现了等待这种状态就是死锁了吗?

其实不一定,我们可以使用两个命令来观测

  1. 使用 jps -l命令,显示本地所有JVM进程,查找当前JVM进程的进程号

  1. 通过jstack命令,显示当前JVM虚拟机的栈信息,查找产生死锁的线程

这就是确定程序出现死锁了

避免死锁的方式

  1. 持有的锁不要超过 1 把
  2. 按相同顺序获得锁,这样没有锁的线程就会进入 blocked 状态

http://www.kler.cn/a/312834.html

相关文章:

  • [ComfyUI]Flux:繁荣生态魔盒已开启,6款LORA已来,更有MJ6写实动漫风景艺术迪士尼全套
  • 算法训练(leetcode)二刷第二十三天 | 455. 分发饼干、*376. 摆动序列、53. 最大子数组和
  • 【电力系统】永磁同步电机调速系统带有扰动观测器
  • nuxt3添加wowjs动效
  • html+js+css实现拖拽式便签留言
  • Python学习从0到1 day27 Python 高阶技巧 ③ 设计模式 — 单例模式
  • Parallels Desktop 20破解版(Mac虚拟机) v20.0.0 for Mac 最新商业版(支持M系列)
  • 揭开数据能力的神秘面纱
  • 当你问AI“有点烦”
  • Python “函数” ——Python面试100道实战题目练习,巩固知识、检查技术、成功就业
  • VSCode的使用
  • 人工智能与量子计算:进展与未来挑战
  • Pyspark dataframe基本内置方法(5)
  • 无线感知会议系列【3】【基于WiFi和4G/5G的非接触无线感知:挑战、理论和应用-1】
  • 【Unity踩坑】UI Image的fillAmount不起作用
  • Oracle 19c异常恢复—ORA-01209/ORA-65088---惜分飞
  • 如何运用专利管理系统的提醒功能,确保专利管理无遗漏?
  • 智能BI项目第五期
  • http免费升级https教程
  • 极狐GitLab CI/CD 功能合集(超详细教程)
  • rtmp推流
  • Linux基础命令——账户简单管理
  • 英集芯IP5902:集成电压可调异步升压转换充电管理功能的8位MCU芯片
  • uniapp使用uview2上传图片功能
  • 通威股份半年报业绩巨降:销售费用大增,近一年股价跌四成
  • 算法-分治和逆序