博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
博为峰Java技术题 ——JavaSE 避免死锁Ⅱ
阅读量:5920 次
发布时间:2019-06-19

本文共 908 字,大约阅读时间需要 3 分钟。

hot3.png

[加锁时限]

博为峰:

另外一个可以避免死锁的方法是在尝试获取锁的时候加一个超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求。若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试。这段随机的等待时间让其它线程有机会尝试获取相同的这些锁,并且让该应用在没有获得锁的时候可以继续运行(超时后可以先继续运行干点其它事情,再回头来重复之前加锁的逻辑)。

以下是一个例子,展示了两个线程以不同的顺序尝试获取相同的两个锁,在发生超时后回退并重试的场景:

5.1tmp_副本.png

在上面的例子中,2比线程1早200毫秒进行重试加锁,因此它可以先成功地获取到两个锁。这时,线程1尝试获取锁A并且处于等待状态。当线程2结束时,线程1也可以顺利的获得这两个锁(除非线程2或者其它线程在线程1成功获得两个锁之前又获得其中的一些锁)。

需要注意的是,由于存在锁的超时,所以我们不能认为这种场景就一定是出现了死锁。也可能是因为获得了锁的线程(导致其它线程超时)需要很长的时间去完成它的任务。

此外,如果有非常多的线程同一时间去竞争同一批资源,就算有超时和回退机制,还是可能会导致这些线程重复地尝试但却始终得不到锁。如果只有两个线程,并且重试的超时时间设定为0到500毫秒之间,这种现象可能不会发生,但是如果是10个或20个线程情况就不同了。因为这些线程等待相等的重试时间的概率就高的多(或者非常接近以至于会出现问题)。 (超时和重试机制是为了避免在同一时间出现的竞争,但是当线程很多时,其中两个或多个线程的超时时间一样或者接近的可能性就会很大,因此就算出现竞争而导致超时后,由于超时时间一样,它们又会同时开始重试,导致新一轮的竞争,带来了新的问题。)

这种机制存在一个问题,在Java中不能对synchronized同步块设置超时时间。你需要创建一个自定义锁,或使用Java5中java.util.concurrent包下的工具。写一个自定义锁类不复杂,但超出了本文的内容。

转载于:https://my.oschina.net/u/2971691/blog/793238

你可能感兴趣的文章
Linux下查看cpu具体信息汇总
查看>>
android 4.0 进行Monkey -- port后的,命令部分列表
查看>>
我的友情链接
查看>>
C#/Java/C/C++基本类型所占大小及表示范围
查看>>
nginx
查看>>
2月第4周国内域名商TOP10:51DNS净减2.3万 份额下跌
查看>>
一台服务器的黑道生涯(连载)之一 初入江湖(原创)
查看>>
我的友情链接
查看>>
简明 Git 命令速查表(中文版)
查看>>
ELK安装使用
查看>>
云HBase小组成功抢救某公司自建HBase集群,挽救30+T数据
查看>>
MSTP+OSPF+VRRP综合实验指导书
查看>>
大数据,处处充满商机,也充满了无限机遇
查看>>
作为一个SEO人员必须要具备的思维
查看>>
linux配置java环境变量(详细)
查看>>
Linux启动之GRUB错误
查看>>
Struts2笔记(5)-----Struts2的校验器
查看>>
Linux crontab 命令
查看>>
SHELL awk 及例子
查看>>
Altas在Ubuntu系统上的安装部署步骤
查看>>