当前位置: 首页 > 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/news/312834.html

相关文章:

  • 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上传图片功能
  • 通威股份半年报业绩巨降:销售费用大增,近一年股价跌四成
  • 算法-分治和逆序
  • 操作系统笔记三
  • Jboss 低版本JMX Console未授权
  • 828华为云征文|华为Flexus云服务器打造FastBee物联网平台
  • Linux Inode 概念、查看、引发的问题及常见解决方案
  • Unity多语言插件I2 Localization国际化应用
  • JAIN SLEE 中Container Managed Persistent (CMP)
  • 使用 Spring Boot + Redis + Vue 实现动态路由加载页面
  • centos 安装VNC,实现远程连接
  • Unity3d开发的C#编码规范
  • 【自然语言处理】补充:布尔模型