并发编程--死锁

简介: 并发编程--死锁

@[toc]

什么是多线程死锁?

同步中嵌套同步,导致锁无法释放

多线程以及多进程改善了系统资源的利用率并提高了系统 的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。
1、系统资源的竞争

通常系统中拥有的不可剥夺资源,其数量不足以满足多个进程运行的需要,使得进程在运行过程中,会因争夺资源而陷入僵局,如磁带机、打印机等。只有对不可剥夺资源的竞争才可能产生死锁,对可剥夺资源的竞争是不会引起死锁的。

2、进程推进顺序不合适

进程在运行过程中,请求和释放资源的顺序不当,也同样会导致死锁。例如,并发进程 P1、P2分别保持了资源R1、R2,而进程P1申请资源R2,进程P2申请资源R1时,两者都会因为所需资源被占用而阻塞。

package com.yxl.demo.ThreadTest;

public class test5 {

    public static void main(String[] args) throws InterruptedException {

        TestDemo thread = new TestDemo();

        Thread t1 = new Thread(thread,"窗口一");
        Thread t2 = new Thread(thread,"窗口二");
        t1.start();
        Thread.sleep(40);
        thread.flag = false;
        t2.start();
    }
}

class TestDemo implements Runnable{
    //共享的火车票变量
    private volatile  int count = 100;

    private  Object object =new Object();

    boolean flag = true;
    //重寫run方法
    @Override
    public void run() {

           if(flag){
               while (count > 0) {
                   synchronized (object) {
                       sale();
                   }
               }
           }else{
               while (count > 0) {

                       sale();

               }
           }


        }



    public synchronized  void sale() {
        try {
            Thread.sleep(50);
        }catch (Exception e){

        }
        synchronized (object) {
            if (count > 0) {
                System.out.println(Thread.currentThread().getName() + "出售 :" + (100 - count + 1));
                count--;
            }
        }
    }

  /*

    public void sale(){
        synchronized (object){
            if(count > 0){
                System.out.println(Thread.currentThread().getName() +"出售 :" +(100 - count + 1));
                count--;
            }
        }
    }*/

}

执行结果:如图所示,红灯一直亮着,锁一直没释放,导致死锁的发生,程序卡住
t1 先获取object锁,在获取this锁,
t2 先获取this锁 ,在获取object锁
在这里插入图片描述

如何解决死锁的发生

  1. 加锁顺序(线程按照一定的顺序加锁)
  2. 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
  3. 死锁检测
相关文章
|
前端开发 UED 索引
React 图片灯箱组件 Image Lightbox
图片灯箱组件是一种常见的Web交互模式,用户点击缩略图后弹出全屏窗口展示大图,并提供导航功能。本文介绍了基于React框架的图片灯箱组件开发,涵盖初始化状态管理、图片加载与预加载、键盘和鼠标事件处理等常见问题及解决方案。通过`useState`和`useEffect`钩子管理状态,使用懒加载和预加载优化性能,确保流畅的用户体验。代码案例展示了组件的基本功能实现,包括打开/关闭灯箱、切换图片及键盘操作。
629 80
|
9月前
|
缓存 监控 Java
拆解一个真实电商项目:微服务架构中的服务治理与性能优化
本课程以母婴电商重构为背景,系统讲解微服务架构落地实践。涵盖服务拆分、Nacos治理、分布式缓存、事务、限流熔断等核心问题,结合Spring Cloud Alibaba技术栈,提供完整项目代码与40小时实战视频,助力开发者掌握从单体到分布式架构的演进能力。
330 14
|
前端开发 JavaScript 测试技术
《存量项目蜕变之路:渐进式引入跨端框架》
在项目中引入跨端框架以实现多平台拓展时,直接重写成本高昂且风险巨大。渐进式引入是一种更可行的方式,它允许在保留原生代码基础上逐步实现新功能或模块的跨端化。首先需谨慎选型框架(如React Native、Flutter、uni-app),结合团队技术栈和项目需求选择最适合的工具。接着从边缘模块入手实践跨端开发,确保与原生代码的通信顺畅,再逐步渗透至核心模块。过程中要调整原生代码结构以更好集成跨端代码,保持应用设计风格和交互体验一致,并通过持续集成与全面测试保障稳定性。这种方式既能降低风险,又能逐步提升应用的多平台适应能力。
374 23
|
存储 API UED
鸿蒙特效教程02-微信语音录制动画效果实现教程
本教程适合HarmonyOS初学者,通过简单到复杂的步骤,一步步实现类似微信APP中的语音录制动画效果。
650 0
鸿蒙特效教程02-微信语音录制动画效果实现教程
|
机器学习/深度学习 人工智能 自然语言处理
|
算法 机器人 中间件
C++的主要优势是什么?
C++的主要优势是什么?
897 1
|
机器学习/深度学习 Java 程序员
Python和C++的区别?
【7月更文挑战第2天】Python和C++的区别?
1170 0