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

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

引言

我们在并发情况下见过很多种锁,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) { // 又获取到了lockBSystem.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.mrgr.cn/news/31187.html

相关文章:

  • ECharts 实现大屏地图功能
  • Ubuntu中以root身份运行Qt创建的项目
  • 【系统设计】理解带宽延迟积(BDP)、吞吐量、延时(RTT)与TCP发送窗口的关系:优化网络性能的关键
  • L2 正则化
  • 温度传感器的工作原理
  • c++零基础入门知识点
  • QEMU 运行Win11 成功的例子
  • fastadmin后台自定义按钮,并且刷新页面
  • 线程池的类型
  • 【测试】博客系统测试报告
  • mybatisplus乐观锁
  • Nginx处理带有分号“;“的路径
  • 【手把手】Windows上安装Python,小白必看
  • 编辑器拓展(入门与实践)
  • VSCode 定义代码模板
  • 云手机的便捷性和安全性体现在哪?
  • Linux--禁止root用户通过ssh直接登录
  • halcon ocr mlp 识别问题
  • 模型参数选择——交叉验证
  • Google Play金融类应用上了又被下,怎么搞定设备短信权限问题?
  • neo4j导入csv数据
  • linux内核 devtmpfs介绍
  • 【Python常用模块】_cx_Oracle模块详解
  • PyQt5中使用文件选择对话框指南
  • nodejs 012:Babel(巴别塔)语言转换与代码兼容
  • PDF样本册如何分享到朋友圈