java并发之死锁

Java系列[多线程并发] -- 关于死锁的讲解与排查 因为热爱所以坚持,因为热爱所以等待。熬过漫长无戏可演的日子,终于换来了人生的春天,共勉!!! 1.什么是死锁? ①死锁:指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。 ②原因: 系统资源不足 进程运行推进的顺序不合适 资源分配不当 ③示意图: 为了更好看清什么是死锁,我们通过代码来写一个死锁 2.编写一个... 阅读详情

上一篇博客 java并发之加锁中主要介绍了在数据库中的加锁问题,现在来聊聊Java中会出现的死锁。
关于死锁,一般教科书的都会罗列满足死锁的几个概念,如互斥、竞态条件等,今天从代码里直接去看死锁,或许会更加直观,直捣黄龙,比记住概念要强得多。


/**
 * @author Jerry
 */
public class ThreadDeadlock {

    public static void main(String[] args) throws InterruptedException {
        Object obj1 = new MyObject("lockA");//这里是几个锁,为下面三个线程共同来争取
        Object obj2 =  new MyObject("lockB");
        Object obj3 = new MyObject("lockC");

        Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1"); //三个线程,注意三个线程加锁的顺序,会形成闭环
        Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
        Thread t3 = new Thread(new SyncThread(obj3,obj1), "t3");

        t1.start();
        Thread.sleep(5000);
        t2.start();
        Thread.sleep(5000);
        t3.start();

    }

}
class MyObject{
    private String name;

    public MyObject(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}
class SyncThread implements Runnable{
    private Object obj1;
    private Object obj2;

    public SyncThread(Object o1, Object o2){
        this.obj1=o1;
        this.obj2=o2;
    }
    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        System.out.println(name + " acquiring lock on "+obj1);
        synchronized (obj1) {
            System.out.println(name + " acquired lock on "+obj1);
            work();
            System.out.println(name + " acquiring lock on "+obj2);
            synchronized (obj2) {//要形成死锁,这里的锁获取要形成嵌套,才会让线程既拥有一个锁又想再去获取另一个
                System.out.println(name + " acquired lock on "+obj2);
                work();
            }
            System.out.println(name + " released lock on "+obj2);
        }
        System.out.println(name + " released lock on "+obj1);
        System.out.println(name + " finished execution.");
    }
    private void work() {
        try {
            Thread.sleep(20000);//模拟耗时操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

最后这里运行结果如下,程序不会终止,没有一个线程释放了锁,线程之间在相互等待,形成了死锁阻塞。

t1 acquiring lock on lockA
t1 acquired lock on lockA
t2 acquiring lock on lockB
t2 acquired lock on lockB
t3 acquiring lock on lockC
t3 acquired lock on lockC
t1 acquiring lock on lockB
t2 acquiring lock on lockC
t3 acquiring lock on lockA

我们如果稍微修改一下代码,将原本 Thread t3 = new Thread(new SyncThread(obj3,obj1), “t3”);
替换成 Thread t3 = new Thread(new SyncThread(obj1,obj3), “t3”);
这样运行的结果如下,可以看出程序不形成死锁,已正常关闭。

t1 acquiring lock on lockA
t1 acquired lock on lockA
t2 acquiring lock on lockB
t2 acquired lock on lockB
t3 acquiring lock on lockA
t1 acquiring lock on lockB
t2 acquiring lock on lockC
t2 acquired lock on lockC
t2 released lock on lockC
t2 released lock on lockB
t2 finished execution.
t1 acquired lock on lockB
t1 released lock on lockB
t1 released lock on lockA
t1 finished execution.
t3 acquired lock on lockA
t3 acquiring lock on lockC
t3 acquired lock on lockC
t3 released lock on lockC
t3 released lock on lockA
t3 finished execution.

或者我们将锁获取方式由嵌套换成一次获取,也就是每次只是持有一个锁,也会得到如上的结果。

syn(lock1){                         syn(lock1){}
    syn(lock2){                     syn(lock2){}
    }
}   

所以避免死锁可以通过每次只获取一个锁或者依次获取锁来避免死锁的问题,当然也可以通过一些超时设定机制来强制退出,解决死锁问题。

Java并发学习三:银行转账的死锁问题解决及示例 Java并发学习系列文章:Java并发学习-博客专栏 今天在学习极客时间专栏:《Java并发编程实战》 从03 | 互斥锁(上):解决原子性问题到06 | 用“等待-通知”机制优化循环等待。 课程主要用银行转账作为解决死锁的例子。 在转账过程中需要2把锁,一个锁锁住转出账户的余额,一把锁锁住转入账户的余额。但加锁的先后顺序会使程序产生死锁。 有以下这四个条件都发生时才会出现死锁: 1.互斥,共... 阅读详情

相关推荐

4、设备树的处理(1)

其实到第4节才写设备树的问题完全是因为忘记了,之前有一个版本是先关闭了设备树的,习惯性的认为设备树已经处理完了,失误了!!!前文说过,这个系统是依着荣品的开发板和核心板来的,使用的是5.1内核的SDK。它的SDK里是开发板全功能的,所以设备树也是的。

wsen2012的博客 417

java并发编程—死锁

java并发编程—死锁

l_010的博客 659

开源DIY龙门架:从零构建可编程运动控制平台

运动控制是自动化与机器人技术的核心基础,它通过精确指令驱动执行机构,实现物体的定位与轨迹规划。其原理通常涉及控制器、驱动器、电机与传动机构的协同工作,核心价值在于将数字指令转化为精准的物理运动,从而解放人力并提升作业一致性。在工业自动化、桌面制造(如3D打印、激光雕刻)及教育机器人等领域应用广泛。本文聚焦于一个具体的工程实践案例:使用**铝型材**、**3D打印**零件、Arduino控制器及步进电机,从机械结构设计、电路连接到代码编写,手把手教你打造一个模块化、可扩展的开源龙门架系统。该系统不仅成本可控,

weixin_33168937的博客 619

Java并发编程--死锁

死锁是指在并发系统中,两个或多个线程或进程互相等待对方持有的资源,从而导致这些线程或进程永久阻塞的状态。简单来说,死锁是系统中一组进程因相互持有对方所需的资源而陷入永久等待的情况。死锁是并发编程中的一个常见问题,会导致程序无法继续执行,需要避免和处理。

Austin_的博客 1304

保姆级教程:在Windows上用Docker Desktop一键部署Dify 1.0.1(附国内镜像加速)

本文提供在Windows系统上使用Docker Desktop快速部署Dify 1.0.1的详细教程,包括环境准备、国内镜像加速配置、Dify容器部署实战及常见问题解决方案。特别针对国内用户优化,确保快速完成部署并提升开发效率。

weixin_33738555的博客 282

Proxmox(pve)集群(4)存储(1)配置分布式存储ceph

它使用一种称为CRUSH(Controlled Replication Under Scalable Hashing)算法的数据分布算法来将数据均匀地分布在多个存储节点上,并确保数据的冗余和容错。它负责管理数据的分布、冗余和自动修复。PVE支持本地存储、LVM、NFS、iSCSI、CephFS、RBD、ZFS等存储方式,我这里使用两种存储方式,一种是通过ceph实现分布式存储,一种是通过truenas实现集中式存储。自我管理和自动恢复:Ceph具有自我管理的特性,可以动态地调整和优化存储集群的配置。

Monster✺◟(∗❛ัᴗ❛ั∗)◞✺的博客 2626

java并发系列之:死锁

在本文中,我们将探讨死锁的概念及其产生的原因,并通过示例代码来说明死锁的出现情况。我们还将介绍如何通过破坏死锁的不同条件来解决死锁问题,通过深入了解死锁及其解决方法,我们可以更好地应对并解决系统中可能出现的死锁情况。本文简单描述了死锁的概念、产生死锁需要满足的四个条件、破坏死锁不同条件的思路和示例。在实战中如何预防死锁、排查死锁,将在后面的文章中补充。若文章中有描述不清或者有误的地方,欢迎评论区讨论与指正!

成为一位优秀的职场人,我在路上 725

SAP中关于预测需求的重要载体:计划独立需求

预测,就是为了调节客户需求的波动、不平衡,使企业的生产计划、物料计划尽量平稳、有序的必备工具。计划独立需求,Planned Independent Requirement(PIR)是SAP系统中最常见的预测需求。

saplakes的博客 1878

Java并发编程学习十二:死锁问题

Java并发编程学习

weixin_41402069的博客 833

用 ADT 的 RAP Generator 把 RAP 栈一键搭起来:从表到可预览的 OData V4 应用

摘要 SAP RAP Generator 工具能显著提升开发效率,通过一键生成从数据库表到完整 OData UI Service 的全套对象(包括 CDS、Behavior、Service Definition 等)。该工具特别适用于原型验证和标准化应用开发,可节省 60% 以上的基础编码时间。使用时需注意: 表设计需包含关键管理字段(如 last_changed 时间戳) 向导配置决定分层架构和命名规范 生成结果包含可立即预览的 Fiori Elements 界面 后续可专注于业务逻辑增强(校验、权限等)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1277

Autosar配置——导入DBC后配置SecOC同步报文和同步请求报文

在Autosar中,安全性是一个重要的考虑因素,而SecOC(Secure On-Board Communication)是一种用于保护通信数据完整性和安全性的安全机制。在上述示例中,我们配置了同步报文和同步请求报文的属性。接下来,我们需要在Autosar中配置同步报文和同步请求报文。同步报文用于在通信双方之间同步SecOC状态,而同步请求报文用于请求SecOC的状态信息。通过以上配置,我们成功地导入了DBC文件,并在Autosar系统中配置了SecOC同步报文和同步请求报文。希望以上信息对您有所帮助!

CyberSphinx的博客 649

java并发--死锁

作者:opLW java并发–死锁 目录 1.什么是死锁 2.出现死锁的原因 3.出现死锁四个必要条件 4.处理死锁的方法 4.死锁,活锁和饥饿的区别 什么是死锁: 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 出现...

opLW的博客 3232

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java并发之死锁详解

带你理解Java并发中的死锁以及解决方法

个人博客,欢迎收藏。 1115

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java并发编程之死锁及死锁预防

Java并发编程之死锁线程死锁数据库死锁 线程死锁 死锁是指两个或多个线程被阻塞,等待获得死锁中的其他线程所持有的锁。当多个线程同时需要相同的锁,但以不同的顺序获得它们时,就会发生死锁。 例如,如果线程1锁定了A并试图锁定B,而线程2已经锁定了B并试图锁定A,那么就会出现死锁。线程1永远不会得到B,线程2永远不会得到a。此外,它们都不会知道。它们将永远阻塞各自的对象A和B。这种情况就是死锁。 Thread1 lock A,wait B Thread2 lock B,wait A 实例代码: TreeN

HQ DevJ的专栏 296

【Java并发】线程死锁

线程死锁,指的是两个或多个线程因争夺资源而互相等待,形成了一个无限循环,导致所有相关线程都无法继续执行的状态。死锁条件含义解决方式示例互斥条件资源不可共享使用读写锁、信号量请求与保持条件一边占有一边请求一次性申请全部资源不可剥夺条件不主动释放资源失败时释放已有资源循环等待条件构成资源环等待链统一加锁顺序,破坏循环死锁发生必须满足互斥、请求与保持、不可剥夺、循环等待四个条件。我们可以通过统一加锁顺序、一次性获取所有资源、使用 tryLock() 限时获取锁。

m0_47352999的博客 1366

Java并发——死锁

死锁是指两个或两个以上的线程,在执行过程中因争夺资源而造成的一种互相等待的现象。若无外力干预,它们都将无法推进下去。简单来说,就是:线程 A 持有资源 1,等待资源 2;线程 B 持有资源 2,等待资源 1。双方都得不到想要的资源,于是永远阻塞。死锁是多线程编程中难以完全避免的问题,但通过理解其产生的四个必要条件,我们可以有针对性地采用预防策略:按顺序申请资源、使用超时锁、减少锁持有时间等。同时,掌握 jstack、JConsole 等工具能帮助我们在问题发生后快速定位。

2301_82251392的博客 347

Java并发编程-如何解决死锁

Java并发编程系列 文章目录Java并发编程系列前言一、锁是什么?二、死锁1.哲学家就餐2.防止死锁总结 前言 本教程中了例子参考了Java高并发编程(第二版)——葛一鸣 一、锁是什么? 锁一般用于并发编程中保护临界区资源的 举个????,同时有多个人去商店买东西,商店中的东西就相当于临界资源,每个人看作一个线程。当某个人去买某件东西时,其他人无法购买的。直到那个人把东西买走释放了锁,商品数量-1,其他人可继续购买。 锁又分为乐观锁和悲观锁 乐观锁认为读多写少,多采用CAS(compare an

Coding&Sharing 298

java 线程并发死锁_【并发编程】java并发编程之死锁

目录死锁是什么?官方定义:死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程(线程)称为死锁进程(线程)。介绍的是不是很抽象?那到底什么是死锁呢?我们来看一个生活中的例子:现有两个仓库,仓库A:存放苹果手机;仓库B:存放华为手机,每天下午4点中都会...

weixin_30667487的博客 176

java死锁几种举例_Java并发——三种典型的死锁

在JAVA并发编程中,我们使用锁来确保可变共享变量的安全性。要注意的是,不正确的使用锁很容易导致死锁。本篇文章转载自:JAVA并发-3种典型的死锁一、死锁产生的条件一般来说,要出现死锁问题需要满足以下条件:互斥条件:一个资源每次只能被一个线程使用。请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。不剥夺条件:线程已获得的资源,在未使用完之前,不能强行剥夺。循环等待条件:若干线程之...

weixin_39569051的博客 340

Java并发编程 死锁的排查

死锁代码 两个线程获取锁的顺序不同就会互相等待,形成死锁 public class DeadLock { public static void main(String[] args) { String lock1 = "lock1",lock2 = "lock2"; new Thread(new DeadLockDemo(lock1,lock2),"A").start(); new Thread(new DeadLockDemo(lock2,lock1

ccccrj博客 355

JAVA并发-3种典型的死锁

在JAVA并发编程中,我们使用锁来确保可变共享变量的安全性。要注意的是,不正确的使用锁很容易导致死锁。死锁的4个必要条件: 1. 互斥访问 2. 非抢占 3. 持有并等待 4. 循环等待在JAVA编程中,有3种典型的死锁类型: 静态的锁顺序死锁,动态的锁顺序死锁,协作对象之间发生的死锁。静态的锁顺序死锁: a和b两个方法都需要获得A锁和B锁。一个线程执行a方法且已经获得了A锁,在等待B锁;另一个线...

义臻的博客 2012

Java并发编程中如何解决死锁问题?

在Java并发编程中,死锁是多个线程因竞争资源陷入相互等待的僵局,导致程序永久阻塞。其发生需同时满足四个必要条件:​​(资源独占)、​​(持有一个资源的同时等待其他资源)、​​(资源仅持有者释放)和​​(线程间形成资源等待环)。

iddlw75046的博客 661

java中的什么是死锁,java并发学习之什么是死锁?死锁的介绍

本篇文章给大家带来的内容是java并发学习之什么是死锁?死锁的介绍。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。 死锁的介绍:锁是一个非常有用的工具,运行场景非常多,因为它使用起来非常简单,而且易于理解。但同时它也会带来一些困扰,比如死锁问题。比如有两个线程A和B,运行都需要两个资源a,b。A获取了a资源,B获取了b资源,接着A去请求b资源,B去请求a资源,两个线程互相阻塞...

weixin_36051064的博客 240

JAVA高并发——无锁与死锁

CAS、原子类Automic、无锁算法、死锁问题

码说芯语的博客 1324
上一篇: java并发之加锁
下一篇: java并发之同步工具类一之闭锁Latch
@云师兄
博客等级 码龄10年 10粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值