互斥锁避免死锁实践
发布日期:2021-07-30 05:57:26
浏览次数:5
分类:技术文章
本文共 2377 字,大约阅读时间需要 7 分钟。
死锁造成的原因
有线程T1 和线程T2 ,T1占用资源A也就是锁住了A对象synchronized(A),T2占用资源B也就是锁住了资源B对象syncrhonized。此时T1线程在去申请获取B对象的时候,T2线程还没有释放资源。T1线程就会一直等待资源B,并且也不会释放资源A.而T2也去申请资源A,就会等待资源A被释放,并且也不会释放资源B. 因此就会形成死锁。
class Account { private int balance; // 转账 void transfer(Account target, int amt){ // 锁定转出账户 synchronized(this){ ① // 锁定转入账户 synchronized(target){ ② if (this.balance > amt) { this.balance -= amt; target.balance += amt; } } } } }
上面的这些代码就会造成死锁。
解决死锁的办法
- 互斥,共享资源 X 和 Y 只能被一个线程占用;
- 占有且等待,线程 T1 已经取得共享资源 X,在等待共享资源Y人时候,不释放共享资源X;
- 不可抢占,其他线程不能强行抢占线程T1占有的资源;
- 循环等待,线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源,就是循环等待。
1.一次性申请多个资源
我们可以创建一个Allocator类,用这个类去申请资源。但是这个类必须是单例的。这样我们就可以避免死锁。
class Allocator { private Allocator(){}; public static Allocator allocator = new Allocator; public static Allocator getAllocator(){ return allocator; } private List
2. 破坏不可抢占条件。
当线程T1无法获取全部资源的时候,就把自己的资源也释放掉。但是这里就无法使用synchronized这个关键字来做了,需要使用Lock关键字来做了。
3. 破坏循环等待条件
我们在加锁的时候,永远让锁资源按照一定的顺序。
class Account { private int id; private int balance; // 转账 void transfer(Account target, int amt){ Account left = this ① Account right = target; ② if (this.id > target.id) { ③ left = target; ④ right = this; ⑤ } ⑥ // 锁定序号小的账户 synchronized(left){ // 锁定序号大的账户 synchronized(right){ if (this.balance > amt){ this.balance -= amt; target.balance += amt; } } } } }
只要做到以上这三点的其中一个就不会出现死锁了。
转载地址:https://blog.csdn.net/u011296165/article/details/89475487 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
做的很好,不错不错
[***.243.131.199]2024年11月22日 11时47分21秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
vcd文件中存储多维数组 vcs_IC设计——EDA软件篇——VCS使用
2019-06-17
thinkphp6实现redis连接池_关于ThinkPHP6多例Redis类实现
2019-06-17
php mysql where and_PHP MYSQL WHERE AND跟OR
2019-06-17
mysql.bin 还原_MySQL binlog 的恢复操作
2019-06-17
mysql5.7.17汉化包_mysql-5.7.17-winx64解压版的安装
2019-06-17
pyspider配置mysql_教你搭建 PySpider 爬虫服务
2019-06-17
mysql for vs2013_Mysql for Visual Studio
2019-06-17
mysql集群 hbase_HBase伪集群配置
2019-06-17
oracle nvl函数 mysql_oracle的nvl函数的使用介绍
2019-06-17
安卓开发能用mysql吗_在安卓开发中使用SQLite数据库操作实例
2019-06-17
mysql实验训练_数据库实验练习
2019-06-17
go 变量大写_Go语言变量的作用域
2019-06-17
python123编程题数值运算程序_实验二 顺序结构程序设计
2019-06-17
python的考试方式_python基础--基本数据类型考试_day3
2019-06-17
怎么把钉钉的文件导入电脑_钉钉文件怎么保存到电脑
2019-06-17
python画版图_基于STC8G8K64U双通道高速ADC采集板
2019-06-17
java过滤xss_Java对类进行XSS过滤
2019-06-17
java求反码_从Java中的取反号‘~’看原码,反码,补码
2019-06-17