标签:log ref 比较 结合 href 获得 art 实现 互斥
转自:lemonGuo
死锁出现的场景
根据以上分析总结一下最坏的情况:
因此,可能出现死锁的情况就是: transfer(a,b,100) 和 transfer(b,a,100)同时进行,这是对双方都很不利的情况:左边的抢走了a的锁,右边的抢走了b的锁。
形成死锁的条件
防止死锁的办法
若要避免死锁,根据以上四个产生死锁的原因,逐一破解即可:
破除互斥等待:不可!锁是保证线程安全的基本方法,无法实现。
破除hold and wait:可以!最关键的一步,就是一次性获取所有资源。例子中的from、to对象是分成两步获取的,从而会形成hold and wait情况,但是通常不允许同时锁两个对象,因此需要对代码做比较大的修改:
破除循环等待:可以!按顺序获取资源。
破除无法剥夺的等待:可以!加入超时。
总结
根据以上的分析,也许你认为第四种加入超时措施相对简单实现,但是如此一来不能使用synchronized,还要暴露一个锁;第二种 from.getAmountLock()
方法实现较复杂。
因此,第二种解决方法较好,即破除循环等待—–按顺序获取资源,出现并发时根据AmountID值先处理值较小的用户,但是这并不是最好的解决方法,因为此解决方法重点为按顺序获取资源,而银行账户中的ID顺序性是我假设出来的,并非实际。
所以,最理想的解决方法还是破除hold and wait,就是一次性获取所有资源!但是通常不允许同时锁两个对象,所以还是先锁住A再锁住B,当B锁不住的时候,把A锁放掉,过段时间再尝试。
完美的解决办法不存在!所以只能根据实际问题具体分析,选择一个折中的办法实现
标签:log ref 比较 结合 href 获得 art 实现 互斥
原文地址:https://www.cnblogs.com/demian/p/9603849.html