Java中死锁的产生以及用编程复现死锁

死锁现象

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

图解

死锁编码

复制代码
  1 package com.lzp.thread;
  2 
  3 import java.util.concurrent.TimeUnit;
  4 
  5 /**
  6  * @Author LZP
  7  * @Date 2021/7/6 14:52
  8  * @Version 1.0
  9  *
 10  * 模拟死锁
 11  * 现有两个女生,两个女生都特别爱打扮自己,每天打扮都要用的两个东西:一个叫梳子(comb),一个叫镜子(mirror)
 12  * 但是此时两人都占着一个,在不放弃自己手中的东西情况下,两位女生都想要再拥有对方拿的东西,这样依赖双方都僵
 13  * 持不下,谁都不肯礼让,这种现象就叫做死锁(竞争共享资源,不释放已有资源)
 14  */
 15 public class DeathLockDemo {
 16 
 17     private final Comb comb = new Comb("梳子");
 18     private final Mirror mirror = new Mirror("镜子");
 19 
 20     public void decorator() {
 21         if (Thread.currentThread().getName().equals("小芳")) {
 22             System.out.println(Thread.currentThread().getName() + "\t 准备梳头发");
 23             synchronized (comb) {
 24                 System.out.println(Thread.currentThread().getName() + "\t 正在使用" + comb.getName());
 25 
 26                 // 休眠1s,让两者都各自占有一个锁
 27                 try {
 28                     TimeUnit.SECONDS.sleep(2);
 29                 } catch (InterruptedException e) {
 30                     e.printStackTrace();
 31                 }
 32 
 33                 System.out.println("过了两分钟后:" + Thread.currentThread().getName() + "\t 准备照镜子");
 34                 synchronized (mirror) {
 35                     System.out.println(Thread.currentThread().getName() + "\t 正在使用" + mirror.getName());
 36                 }
 37                 System.out.println(Thread.currentThread().getName() + "\t 镜子用好了");
 38             }
 39             System.out.println(Thread.currentThread().getName() + "\t 梳子用好了");
 40         } else {
 41             System.out.println(Thread.currentThread().getName() + "\t 准备照镜子");
 42             synchronized (mirror) {
 43                 System.out.println(Thread.currentThread().getName() + "\t 正在使用" + mirror.getName());
 44 
 45                 // 休眠1s,让两者都各自占有一个锁
 46                 try {
 47                     TimeUnit.SECONDS.sleep(2);
 48                 } catch (InterruptedException e) {
 49                     e.printStackTrace();
 50                 }
 51 
 52                 System.out.println("过了两分钟后:" + Thread.currentThread().getName() + "\t 准备梳头发");
 53                 synchronized (comb) {
 54                     System.out.println(Thread.currentThread().getName() + "\t 正在使用" + comb.getName());
 55                 }
 56                 System.out.println(Thread.currentThread().getName() + "\t 梳子用好了");
 57             }
 58             System.out.println(Thread.currentThread().getName() + "\t 镜子用好了");
 59         }
 60         System.out.println(Thread.currentThread().getName() + "\t 打扮好了");
 61     }
 62 
 63     public static void main(String[] args) {
 64         DeathLockDemo deathLockDemo = new DeathLockDemo();
 65 
 66         new Thread(deathLockDemo::decorator, "小芳").start();
 67 
 68         new Thread(deathLockDemo::decorator, "露露").start();
 69     }
 70 }
 71 
 72 // 梳子
 73 class Comb {
 74     private String name;
 75 
 76     public Comb(String name) {
 77         this.name = name;
 78     }
 79 
 80     public String getName() {
 81         return name;
 82     }
 83 
 84     public void setName(String name) {
 85         this.name = name;
 86     }
 87 }
 88 
 89 // 镜子
 90 class Mirror {
 91     private String name;
 92 
 93     public Mirror(String name) {
 94         this.name = name;
 95     }
 96 
 97     public String getName() {
 98         return name;
 99     }
100 
101     public void setName(String name) {
102         this.name = name;
103     }
104 }
复制代码

运行结果:

 

posted @   没有你哪有我  阅读(169)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
点击右上角即可分享
微信分享提示