【死锁分享】Java面试官: 请说一个死锁的案例?

简介: 简单案例分享死锁,入门学习!
【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!

博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!

吾等采石之人,应怀大教堂之心,愿大家奔赴在各自的热爱里…

一、初识死锁

面试官:谈一下你对死锁的理解?
请添加图片描述

死锁就是两个或多个线程(或进程)被无限期地阻塞,相互等待对方手中资源的一种状态

一旦发生了死锁,根据发生死锁的线程的职责不同,就可能会造成 子系统崩溃、性能降低 甚至 整个系统崩溃 等各种不良后果。而且死锁往往发生在高并发、高负载的情况下,因为可能会直接影响到很多用户,造成一系列的问题


Java 死锁产生的四个必要条件:

1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路

打破死锁即打破如上四个中的一个满足条件即可


二、案例分析

面试官:请简单的写出一个具体的死锁案例!

请添加图片描述

如下两个对象在调度a资源的时候需要调度b资源,同时调度b资源的时候需要调度a资源,资源得不到释放,产生死锁

/**
 * 2021-9-11 15:52:43
 * 辰兮要努力
 */
public class TestDeadLock {
    /*
     * 所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进
     */

    public static void main(String[] args) {
       //创建两个资源 a资源和b资源互相调度
        final Object a = new Object();
        final Object b = new Object();


       //线程A,按照先锁a再获得锁b的的顺序获得锁
        new Thread() {
            @Override
            public void run(){
                    synchronized (a) {
                        System.out.println(Thread.currentThread().getName()+ "线程 已获取 a资源");

                        try {
                            //线程睡两秒
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()+ "线程 想获取 b资源");
                        synchronized (b) {
                            System.out.println(Thread.currentThread().getName() + "win");
                        }
                    }
            }
        }.start();

        //线程B先获取锁b再锁a的顺序获得锁
        new Thread() {
            @Override
            public void run(){
                synchronized (b) {
                    System.out.println(Thread.currentThread().getName()+ "线程 已获取 b资源");
                    //线程睡两秒
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+ "线程 想获取 a资源");
                    synchronized (a) {
                        System.out.println(Thread.currentThread().getName() + "win");
                    }
                }
            }
        }.start();
        
    }
}

执行效果如下
在这里插入图片描述

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去


三、排查解决

面试官:你如何排查项目中的死锁问题呢?
请添加图片描述

jps(Java Virtual Machine Process Status Tool)

jps是java提供的一个显示当前所有java进程pid的命令,适合在linux/unix平台上简单察看当前java进程的一些简单情况

在这里插入图片描述
输入的效果

C:\Users\lenovo>jps
10608 TestDeadLock
10848 Launcher
6640
18408 Jps
18460 KotlinCompileDaemon

jstack是java虚拟机自带的一种堆栈跟踪工具。

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因

C:\Users\lenovo>jstack 10608

输入的效果
在这里插入图片描述

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x0000000003488e08 (object 0x000000076be21938, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x000000000348b698 (object 0x000000076be21948, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.chenxi.TestDeadLock$2.run(TestDeadLock.java:53)
        - waiting to lock <0x000000076be21938> (a java.lang.Object)
        - locked <0x000000076be21948> (a java.lang.Object)
"Thread-0":
        at com.chenxi.TestDeadLock$1.run(TestDeadLock.java:33)
        - waiting to lock <0x000000076be21948> (a java.lang.Object)
        - locked <0x000000076be21938> (a java.lang.Object)

Found 1 deadlock.

如上的日志
"Thread-1":等待的去锁 <0x000000076be21938>
同时已经锁住了 <0x000000076be21948>

"Thread-0":等待的去锁 <0x000000076be21948>
同时已经锁住了<0x000000076be21938>

Found 1 deadlock.

同时日志里面有产生死锁的类和具体的行数

如上的方法我们可以准确的定位到死锁具体产生的位置,具体的业务场景就根据具体的情况分析解决


非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤️ 分享👥 留言💬thanks!!!

愿你们奔赴在自己的热爱里!

目录
相关文章
|
25天前
|
Java 程序员
java线程池讲解面试
java线程池讲解面试
43 1
|
29天前
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
21 1
|
21天前
|
SQL 设计模式 安全
Java单例模式几种写法以及代码案例拿来直接使用
Java单例模式几种写法以及代码案例拿来直接使用
31 0
|
29天前
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
Mybatis+mysql动态分页查询数据案例——工具类(MybatisUtil.java)
15 1
|
4天前
|
XML 缓存 Java
Java大厂面试题
Java大厂面试题
14 0
|
4天前
|
存储 安全 Java
Java大厂面试题
Java大厂面试题
10 0
|
4天前
|
存储 安全 Java
Java大厂面试题
Java大厂面试题
12 0
|
5天前
|
安全 Java
就只说 3 个 Java 面试题 —— 02
就只说 3 个 Java 面试题 —— 02
17 0
|
5天前
|
存储 安全 Java
就只说 3 个 Java 面试题
就只说 3 个 Java 面试题
10 0
|
5天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例

热门文章

最新文章