Java面试题:什么是死锁?如何手写一个死锁(Dead Lock)

2024-06-15 07:38

本文主要是介绍Java面试题:什么是死锁?如何手写一个死锁(Dead Lock),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

要想实现一个死锁,首先要明白什么是死锁,我们看一下死锁的定义:

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。--百度

用通俗的话来说就是张三跟李四下饭馆吃饺子,张三拿着醋,李四拿着蒜瓣,张三说李四你给我吃点蒜,李四说,那不行,你得先给我醋,要不然我不给你,张三也不乐意了,说你必须先给我蒜瓣,我再给你醋,这种现象就是死锁。(Dead Lock)

我们知道使用Synchronize锁两个对象很容易发生这种事,话不多说,直接上代码:

package Thread;public class DumplingDeadLockDemo implements Runnable{static Object garlic = new Object();static Object vinegar = new Object();int flag = 0;@Overridepublic void run() {if (flag == 0) {synchronized (vinegar) {try {Thread.sleep(500);} catch (InterruptedException e) {return;}System.out.println("我张三正在吃醋,李四你给我点蒜瓣");synchronized (garlic) {System.out.println("我张三终于吃上蒜了,hiahia~");}}}if (flag == 1) {synchronized (garlic) {try {Thread.sleep(500);} catch (InterruptedException e) {}System.out.println("俺李四正在吃蒜,张三你给我点醋");synchronized (vinegar) {System.out.println("我李四终于吃上醋了,hiahia~");}}}}public static void main(String[] args) {DumplingDeadLockDemo ZhangSan = new DumplingDeadLockDemo();DumplingDeadLockDemo LiSi = new DumplingDeadLockDemo();ZhangSan.flag = 0;LiSi.flag = 1;Thread t1 = new Thread(ZhangSan);Thread t2 = new Thread(LiSi);t1.start();t2.start();}
}

需要注意,新手容易犯的错是把两个synchronized分开写了,那么就永远都不会成了死锁,死锁发生的四个必要条件是:

1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

 

拿我这个例子来说,想要死锁,必须满足:

互斥性:张三和李四必须吃了醋再吃蒜或者吃了蒜再吃醋,两个事件不可同时发生,否则不满足互斥性自然也不会构成死锁。

请求和保持条件:至少保证张三拿着醋,李四拿着蒜瓣,但是张三还非得要吃蒜,李四还非得吃醋,否则缺少一个条件都不构成死锁。

不剥夺条件:张三拿着醋,没完成吃蒜这个事件,李四绝对不能过来抢,否则不满足不剥夺条件。

环路等待条件:

一定要构成这种环形等待。

 

这篇关于Java面试题:什么是死锁?如何手写一个死锁(Dead Lock)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1062830

相关文章

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

Java内存分配与JVM参数详解(推荐)

《Java内存分配与JVM参数详解(推荐)》本文详解JVM内存结构与参数调整,涵盖堆分代、元空间、GC选择及优化策略,帮助开发者提升性能、避免内存泄漏,本文给大家介绍Java内存分配与JVM参数详解,... 目录引言JVM内存结构JVM参数概述堆内存分配年轻代与老年代调整堆内存大小调整年轻代与老年代比例元空

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

SpringBoot整合liteflow的详细过程

《SpringBoot整合liteflow的详细过程》:本文主要介绍SpringBoot整合liteflow的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...  liteflow 是什么? 能做什么?总之一句话:能帮你规范写代码逻辑 ,编排并解耦业务逻辑,代码

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

Spring Security中用户名和密码的验证完整流程

《SpringSecurity中用户名和密码的验证完整流程》本文给大家介绍SpringSecurity中用户名和密码的验证完整流程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 首先创建了一个UsernamePasswordAuthenticationTChina编程oken对象,这是S