死锁简单解释:
就是(进程/线程)对象1,占据资源A,同时申请资源B,而(进程/线程)对象2,占据资源B,同时申请资源A,
如果双方均阻塞等待,且不释放已占用资源,这就发生了死锁。
死锁的发生:
如果程序比较简单,结构清晰,正常情况下死锁是完全能够很清晰的做到人为避免的。但是事实却是死锁会在不经意间
就发生了,我们永远记住一个道理:程序结构与思路做到简单清晰是第一战略,永远不要试图用你所谓的聪明才智去挑战复
杂的程序逻辑,否则迟早会跌一个你爬都爬不起来的跟头。
如何解决呢:
1) 把逻辑做到最简捷,一目了然最好,即使有问题,解决起来也是分分钟的事情,因为事先的设计上你已经下足了功夫。
2) 稍微复杂一点的,可以通过仔细的控制加锁的顺序来避免思索的发生。比如有三个临界锁ABC, 在所有使用的地方
严格按照统一顺序加锁、解锁。注意顺序使用当中后继锁对象可以省略,前驱一定不能省。
比如((进程/线程)对象1) 使用 A-B-C 顺序申请锁,那么其他(进程/线程)对象,可使用顺组组合: A;A-B ;A-B-C
3) 有时候对互斥量的锁排序是困难的,不容易做成简单的层次,(在自己力所能及的情况下,总应该设计出强制的层级顺序),
就需要另外一种方法:即使通过破解死锁条件的几个条件来入手:
a.释放自己也已占用的资源,过一段时间再重试,
b.使用“尝试”加锁接口,避免长时间阻塞。
4)增大锁的粒度,减少锁的个数,来化简程序逻辑结构,这有可能会降低程序的并发性能(也要参考锁本身的系统开销,
锁的粒度也是要讲究一个平衡),当然在满足锁需求的情况下,在代码复杂度和性能之间找到一个平衡。
5)其他一些更高级的技术:无锁算法,乒乓缓存,等等,更重要的是结合实际的业务逻辑找到一个合适的点。
总结
程序设计本身就是平衡的艺术,时间与空间的平衡,性能与代价的平衡、 成本与收益的平衡,设计与需求的平衡。