java线程(16)——死锁讲解,白雪公主与灰姑娘抢口红和镜子的案例
1.死锁代码
//死锁:多个线程互相抱着对方需要的资源,然后形成僵局
public class DeadLock {public static void main(String[] args) {Makeup girl1 = new Makeup(0,"灰姑娘");Makeup girl2 = new Makeup(1,"白雪公主");girl1.start();girl2.start();}}//口红
class Lipstick{}//镜子
class Mirror{}class Makeup extends Thread{//需要的资源只能有一份,用static来保证只有一份static Lipstick lipstick = new Lipstick();static Mirror mirror = new Mirror();int choice;//选择String girlName;//使用化妆品的人public Makeup(int choice, String girlName) {this.choice = choice;this.girlName = girlName;}@Overridepublic void run(){try {makeup();//化妆} catch (InterruptedException e) {e.printStackTrace();}}private void makeup() throws InterruptedException {if (choice == 0){synchronized (lipstick){//获得口红的锁System.out.println(this.girlName+"获得口红的锁");Thread.sleep(1000);synchronized (mirror){//一秒钟后想获得镜子System.out.println(this.girlName+"获取镜子的锁");}}}else {synchronized (mirror){//获得镜子的锁System.out.println(this.girlName+"获得镜子的锁");Thread.sleep(2000);synchronized (lipstick){//两秒钟后,想获得口红System.out.println(this.girlName+"获取口红的锁");}}}}
}
关键代码
private void makeup() throws InterruptedException {if (choice == 0){synchronized (lipstick){//获得口红的锁System.out.println(this.girlName+"获得口红的锁");Thread.sleep(1000);synchronized (mirror){//一秒钟后想获得镜子System.out.println(this.girlName+"获取镜子的锁");}}}else {synchronized (mirror){//获得镜子的锁System.out.println(this.girlName+"获得镜子的锁");Thread.sleep(2000);synchronized (lipstick){//两秒钟后,想获得口红System.out.println(this.girlName+"获取口红的锁");}}}}
上述代码解析,当一个线程A锁住口红不放,同时想拿镜子
但是镜子被线程B锁住,线程B要拿到了口红才会释放镜子
那么线程A就会一直等待线程B释放镜子锁
但是线程B要拿不到口红锁就不会释放镜子锁
所以两个线程互相等待,形成死锁,程序崩溃
运行结果
2.解决后的代码
private void makeup() throws InterruptedException {if (choice == 0){synchronized (lipstick){//获得口红的锁System.out.println(this.girlName+"获得口红的锁");Thread.sleep(1000);}synchronized (mirror){//一秒钟后想获得镜子System.out.println(this.girlName+"获取镜子的锁");}}else {synchronized (mirror){//获得镜子的锁System.out.println(this.girlName+"获得镜子的锁");Thread.sleep(2000);}synchronized (lipstick){//两秒钟后,想获得口红System.out.println(this.girlName+"获取口红的锁");}}}
线程A拿到了口红锁,然后释放了口红锁,想拿镜子锁
线程B拿到了镜子锁,然后释放了镜子锁,再拿口红锁
双方达成共识,不会永久的等待
运行结果
java线程(16)——死锁讲解,白雪公主与灰姑娘抢口红和镜子的案例相关推荐
- java线程饥饿死锁_java并发-线程饥饿死锁测试
线程饥饿死锁 <Java并发编程实践>中对线程饥饿死锁的解释是这样的:在使用线程池执行任务时,如果任务依赖于其他任务,那么就可能产生死锁问题.在单线程的Executor中,若果一个任务将另 ...
- Java线程的死锁和活锁
文章目录 1.概览 2.死锁 2.1.什么是死锁 2.2 死锁举例 2.3 避免死锁 3.活锁 3.1 什么是活锁 3.2 活锁举例 3.3 避免活锁 1.概览 当多线程帮助我们提高应用性能的同时,它 ...
- java线程池深入讲解_死磕 java线程系列之线程池深入解析——生命周期
(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 上一章我们一起重温了下线程的 ...
- java线程死锁_Java线程死锁–案例研究
java线程死锁 本文将描述从在IBM JVM 1.6上运行的Weblogic 11g生产系统中观察到的最新Java死锁问题的完整根本原因分析. 此案例研究还将证明掌握线程转储分析技能的重要性: 包括 ...
- Java线程死锁–案例研究
本文将描述从在IBM JVM 1.6上运行的Weblogic 11g生产系统中观察到的最新Java死锁问题的完整根本原因分析. 此案例研究还将证明掌握线程转储分析技能的重要性: 包括用于IBM JVM ...
- Java线程通俗讲解
Java线程介绍 通常情况下,在一个服务器上面运行的程序是很多的,可能同一时间会有多个客户 端的程序访问服务器,服务器都要对这些客户端做出响应.如果我们处理器有限, 只有一个处理器的时候,如何能够让这 ...
- java中线程死锁及避免_如何避免Java线程中的死锁?
java中线程死锁及避免 如何避免Java中的死锁? 是Java面试中最受欢迎的问题之一,也是本季多线程的风格,主要是在高层提出,并带有很多后续问题. 尽管问题看起来很基础,但是一旦您开始深入研究,大 ...
- 如何避免Java线程中的死锁?
如何避免Java死锁? 是Java面试中最受欢迎的问题之一,也是本季多线程的风格,主要是在高层提出,并带有很多后续问题. 尽管问题看起来很基础,但是一旦您开始深入研究,大多数Java开发人员就会陷入困 ...
- java线程死锁_Java并发:隐藏线程死锁
java线程死锁 大多数Java程序员熟悉Java线程死锁概念. 它本质上涉及2个线程,它们彼此永远等待. 这种情况通常是平面(同步)或ReentrantLock(读或写)锁排序问题的结果. Foun ...
最新文章
- apache hadoop 2.4.0 64bit 在windows8.1下直接安装指南(无需虚拟机和cygwin)
- python 平滑曲线
- web前端技巧-ES6新特性与重点知识汇总(一)
- Python基础——PyCharm版本——第二章、数据类型和变量(超详细)
- 步步为营:Asp.Net序列化Json格式的两种方法
- 【无标题】写博客的第一天
- 人机身份验证开发资料
- win 7更改计算机用户名和密码错误,解决win7一开机就显示用户名和密码错误故障...
- Pseudo Labelling
- 计算机硬盘图标ico,LaCie 硬盘图标
- @Resource详解
- Hackintosh(黑苹果)bigsur (opencore引导)超级详细教程
- python大鱼吃小鱼单机游戏下载_大鱼吃小鱼
- 【华为2019年校园招聘】2019-4-17 软件题-水果摊小买卖
- python语言是什么语言-python是一门什么样的语言?
- 【直播聊天室】特点、构成及解决方案简介
- c聊天室系统asp ajax,利用AJAX和ASP.NET实现简单聊天室
- [2018 CS:GO Client]2018 Old CSGO 客户端,回忆逝去的青春!
- 宏碁欲做行业老大 华硕推“巨狮计划”
- 中国色—在线的中国传统颜色集锦