java安全编码指南之:死锁dead lock

简介

java中为了保证共享数据的安全性,我们引入了锁的机制。有了锁就有可能产生死锁。

死锁的原因就是多个线程锁住了对方所需要的资源,然后现有的资源又没有释放,从而导致循环等待的情况。

通常来说如果不同的线程对加锁和释放锁的顺序不一致的话,就很有可能产生死锁。

不同的加锁顺序

我们来看一个不同加锁顺序的例子:

public class DiffLockOrder {private int amount;public DiffLockOrder(int amount){this.amount=amount;}public void transfer(DiffLockOrder target,int transferAmount){synchronized (this){synchronized (target){if(amount< transferAmount){System.out.println("余额不足!");}else{amount=amount-transferAmount;target.amount=target.amount+transferAmount;}}}}
}

上面的例子中,我们模拟一个转账的过程,amount用来表示用户余额。transfer用来将当前账号的一部分金额转移到目标对象中。

为了保证在transfer的过程中,两个账户不被别人修改,我们使用了两个synchronized关键字,分别把transfer对象和目标对象进行锁定。

看起来好像没问题,但是我们没有考虑在调用的过程中,transfer的顺序是可以发送变化的:

        DiffLockOrder account1 = new DiffLockOrder(1000);DiffLockOrder account2 = new DiffLockOrder(500);Runnable target1= ()->account1.transfer(account2,200);Runnable target2= ()->account2.transfer(account1,100);new Thread(target1).start();new Thread(target2).start();

上面的例子中,我们定义了两个account,然后两个账户互相转账,最后很有可能导致互相锁定,最后产生死锁。

使用private类变量

使用两个sync会有顺序的问题,那么有没有办法只是用一个sync就可以在所有的实例中同步呢?

有的,我们可以使用private的类变量,因为类变量是在所有实例中共享的,这样一次sync就够了:

public class LockWithPrivateStatic {private int amount;private static final Object lock = new Object();public LockWithPrivateStatic(int amount){this.amount=amount;}public void transfer(LockWithPrivateStatic target, int transferAmount){synchronized (lock) {if (amount < transferAmount) {System.out.println("余额不足!");} else {amount = amount - transferAmount;target.amount = target.amount + transferAmount;}}}
}

使用相同的Order

我们产生死锁的原因是无法控制上锁的顺序,如果我们能够控制上锁的顺序,是不是就不会产生死锁了呢?

带着这个思路,我们给对象再加上一个id字段:

    private final long id; // 唯一ID,用来排序private static final AtomicLong nextID = new AtomicLong(0); // 用来生成IDpublic DiffLockWithOrder(int amount){this.amount=amount;this.id = nextID.getAndIncrement();}

在初始化对象的时候,我们使用static的AtomicLong类来为每个对象生成唯一的ID。

在做transfer的时候,我们先比较两个对象的ID大小,然后根据ID进行排序,最后安装顺序进行加锁。这样就能够保证顺序,从而避免死锁。

    public void transfer(DiffLockWithOrder target, int transferAmount){DiffLockWithOrder fist, second;if (compareTo(target) < 0) {fist = this;second = target;} else {fist = target;second = this;}synchronized (fist){synchronized (second){if(amount< transferAmount){System.out.println("余额不足!");}else{amount=amount-transferAmount;target.amount=target.amount+transferAmount;}}}}

释放掉已占有的锁

死锁是互相请求对方占用的锁,但是对方的锁一直没有释放,我们考虑一下,如果获取不到锁的时候,自动释放已占用的锁是不是也可以解决死锁的问题呢?

因为ReentrantLock有一个tryLock()方法,我们可以使用这个方法来判断是否能够获取到锁,获取不到就释放已占有的锁。

我们使用ReentrantLock来完成这个例子:

public class DiffLockWithReentrantLock {private int amount;private final Lock lock = new ReentrantLock();public DiffLockWithReentrantLock(int amount){this.amount=amount;}private void transfer(DiffLockWithReentrantLock target, int transferAmount)throws InterruptedException {while (true) {if (this.lock.tryLock()) {try {if (target.lock.tryLock()) {try {if(amount< transferAmount){System.out.println("余额不足!");}else{amount=amount-transferAmount;target.amount=target.amount+transferAmount;}break;} finally {target.lock.unlock();}}} finally {this.lock.unlock();}}//随机sleep一定的时间,保证可以释放掉锁Thread.sleep(1000+new Random(1000L).nextInt(1000));}}}

我们把两个tryLock方法在while循环中,如果不能获取到锁就循环遍历。

 

原文链接
本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/514949.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

山石网科发布重磅容器安全产品“山石云铠”,云安全版图再下一城

编辑 | 宋 慧 出品 | CSDN云计算 5月18日&#xff0c;山石网科正式发布了云安全的重磅新品——山石云铠。至此&#xff0c;山石网科云计算安全版图补全“容器安全”板块&#xff0c;已完成目前主流虚拟化技术及云服务场景网络安全产品的全面覆盖。 虽然是非常重要的产品发布&…

如何提升微服务的幸福感?

![1.png](https://ucc.alicdn.com/pic/developer-ecology/5dffeef22eb74645a35be2f60b5e54c6.png) 作者 | 亦盏 前言 随着微服务的流行&#xff0c;越来越多公司使用了微服务框架&#xff0c;微服务以其高内聚、低耦合等特性&#xff0c;提供了更好的容错性&#xff0c;也…

平台式可复用的应用集成能力,助您敏捷、高效的完成企业数字化转型

简介&#xff1a; 企业数字化转型往往是一个长期持续的过程&#xff0c;产品变革和技术迭代也在加速演进&#xff0c;连接性是数字化转型的关键推动因素&#xff0c;甚至将决定成败。为了应对普遍的集成要求&#xff0c;企业需要新一代更敏捷的集成能力框架&#xff0c;基于高效…

携程发布2021年一季度财报:净利润环比增长近80% 达18亿元人民币

北京时间2021年5月19日, 携程集团&#xff08;纳斯达克&#xff1a;TCOM及香港联交所&#xff1a;9961&#xff09;公布了截至2021年3月31日第一季度未经审计的财务业绩。 在全球旅游业饱受疫情冲击&#xff0c;国内疫情防控政策在年初收紧的背景下&#xff0c;今年一季度&…

阿里云DNS 新增云上线路的智能解析功能

简介&#xff1a; 企业在云上部署单元化架构或内部服务链路时&#xff0c;需要考虑让数据&#xff08;单元&#xff09;离用户更近&#xff0c;避免跨单元获取数据&#xff0c;以此来满足自身低延时的诉求。阿里云DNS 新增基于云上链路的调度功能&#xff0c;进一步优化DNS智能…

进击的数据中台,企业数字化转型的新引擎

经历过“追捧”和“质疑”等种种考验后&#xff0c;当前&#xff0c;数据中台已经走到验证其价值的关键路口。 数据中台是企业数字化转型新引擎 在人工智能、大数据等技术发展和企业数字化转型加速的双重驱动下&#xff0c;2019年&#xff0c;数据中台在众多赛道中脱颖而出&a…

关于低代码真实技术趋势,听低代码巨头 Mendix 怎么说

作者 | 宋慧 出品 | CSDN云计算 在 2021年初正式宣布进入中国市场 之后&#xff0c;Mendix 在近日向媒体重点披露了关于低代码的技术方法论&#xff0c;以及近四个月在中国市场的进展。 Mendix 的低代码技术方法论 对于低代码常被讨论的模型驱动部分&#xff0c;Mendix 希望做…

架构设计的本质

简介&#xff1a; 实际上架构只是系统设计里面的一个重要环节&#xff0c;除了架构还包含了商业诉求&#xff0c;业务建模&#xff0c;系统分析&#xff0c;系统设计等重要领域。本文尝试从更高视角重新审视架构设计的工作&#xff0c;把架构设计的上升到系统设计的立体空间去探…

java安全编码指南之:方法编写指南

简介 java程序的逻辑是由一个个的方法组成的&#xff0c;而在编写方法的过程中&#xff0c;我们也需要遵守一定的安全规则&#xff0c;比如方法的参数进行校验&#xff0c;不要在assert中添加业务逻辑&#xff0c;不要使用废弃或者过期的方法&#xff0c;做安全检查的方法一定…

ios 蓝牙命令发送_实战恢复cisco 2950交换机的IOS

本来想用两台思科交换机做实验的&#xff0c;可是通过console口进入其中一台交换机后却发现这个台交换机的IOS文件丢失了。本来正常进入交换机后应该是首先进入到用户模式的&#xff0c;而且提示符应该是“>”&#xff0c;而现在提示符却成了“&#xff1a;”&#xff0c;如…

还在担心无代码是否威胁程序员饭碗?

作者 | 伍杏玲头图 | 下载于ICphoto出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;近几年来&#xff0c;“低代码/无代码”概念广为热议。然而低代码并不是新鲜词&#xff0c;实则是IT 界对简化代码开发的需求促使。早在 1982 年&#xff0c;詹姆斯马丁在《…

过Serverless技术降低微服务应用资源成本

前言 在大型分布式IT架构领域&#xff0c;微服务是一项必不可少的技术。从本质上来讲&#xff0c;微服务是一种架构风格&#xff0c;将一个大型的系统拆分为多个拥有独立生命周期的应用&#xff0c;应用之间采用轻量级的通信机制进行通信。这些应用都是围绕具体业务进行构建&a…

ethercat 网卡不兼容_曾经的洋垃圾万兆网卡无人问津因为一张转接卡如今身价暴涨数十倍...

今天老水要跟大家介绍的是最近非常火爆的ocp万兆网卡&#xff0c;为啥非常火爆呢&#xff1f;因为他的价格非常的低廉&#xff0c;性能非常的强劲&#xff0c;最开始的时候售价只要8块钱一张&#xff0c;但是却无人问津&#xff0c;这又是为啥&#xff1f;ocp网卡视频&#xff…

在淘宝,我们是这样衡量代码质量的

简介&#xff1a; ![img](https://img.alicdn.com/tfs/TB1ZTW4VEY1gK0jSZFMXXaWcVXa-2304-1194.png) **越高级别的程序员往往越看重代码质量。** 本篇文章主要聊一下在团队开发过程中&#xff0c;如何做到代码质量的管控与提升。首先需要有一套规范&#xff0c;定义什么是好的代…

SpringBoot项目在logback.xml中读取application.properties中配置的日志路径

文章目录一、问题二、原因三、LOGBACK.XML中读取配置中的日志路径方案3.1. 方案一3.2. 方案二一、问题 在SpringBoot项目&#xff0c;使用logback.xml中配置日志的存储位置时&#xff0c;读取application.properties或application.yml中配置的路径&#xff0c;在logback.xml中…

Java知识全面总结:并发编程+JVM+设计模式+常用框架+....

本文整理的Java知识体系主要包括基础知识&#xff0c;工具&#xff0c;并发编程&#xff0c;数据结构与算法&#xff0c;数据库&#xff0c;JVM&#xff0c;架构设计&#xff0c;应用框架&#xff0c;中间件&#xff0c;微服务架构&#xff0c;分布式架构等内容。同时也有作为程…

智能消息服务-数字短信使用FAQ简介: 数字短信是基于普通短信,通过一套编码技术实现的短信服务。它能把视频、音频、网页、GIF图、文字等多种表现形式通过多媒体短信形式触达用户。本文将带你了解阿里云通信

简介&#xff1a; 数字短信是基于普通短信&#xff0c;通过一套编码技术实现的短信服务。它能把视频、音频、网页、GIF图、文字等多种表现形式通过多媒体短信形式触达用户。本文将带你了解阿里云通信数字短信产品的开通与使用。 一、数字短信功能如何开通&#xff1f; 1.开通…

xxl-job registry fail, registryParam:RegistryParam{regist

在项目集成xxl-job发现执行器一直注册不上去&#xff0c;心跳报错。 xxl-job registry fail, registryParam:RegistryParam{registryGroup‘EXECUTOR’, registryKey‘xxl-job-invoice-api’, registryValue‘http://xxxxxx:9990/’}, registryResult:ReturnT [code500, msgTh…

台达b3伺服参数设置方法_2020东莞清溪台达自动化配件回收厂家直购

2020东莞清溪台达自动化配件回收厂家直购在不同的工业控制系统中&#xff0c;工控软件虽然完成的功能不同&#xff0c;但就其结构来说&#xff0c;一般具有如下特点&#xff1a;实时性&#xff1a;工业控制系统中有些事件的发生具有随机性&#xff0c;要求工控软件能够及时地处…

3千字带你搞懂XXL-JOB任务调度平台

思维导图 文章已收录Github精选&#xff0c;欢迎Star&#xff1a;https://github.com/yehongzhi/learningSummary 一、概述 在平时的业务场景中&#xff0c;经常有一些场景需要使用定时任务&#xff0c;比如&#xff1a; 时间驱动的场景&#xff1a;某个时间点发送优惠券&…