![d83ad486117411c9cb99867570f09373.png](https://img-blog.csdnimg.cn/img_convert/d83ad486117411c9cb99867570f09373.png)
多线程开发避不开锁,而锁又避不开死锁问题,所以弄清楚死锁问题才能开发出好的多线程程序。
死锁出现原因与解决方法
在多线程开发中,都是通过加锁来保证线程安全,但是过度的使用锁可能导致死锁。在数据库系统中有对死锁的检测并从死锁中恢复功能,一个事务可能会获取多个锁,当多个事务发生死锁,会选择牺牲一个事务,释放这个事务的所有锁,然后重新执行。而Java程序无法从死锁中恢复过来,因此在设计时一定要排除那些导致死锁出现的条件。
获取锁顺序造成死锁
而最简单的死锁是线程A持有资源M并想获取资源N,线程B持有资源N并想获取M,造成线程互相等待出现死锁。
造成这种死锁的原因是获取锁顺序不一致。所以解决方案是所有线程以固定的顺序来获得锁,那么在程序中就不会出现锁顺序死锁问题。
动态锁造成死锁
现在有一个转账程序,当A转账给B时,先获取A的锁在获取B锁,表面上似乎没有问题,但是如果同时又出现B转账给A,所以它会先锁B在锁A,造成死锁。这种不是代码层面的锁而是数据层面不容易发现。
要解决这种问题的根本办法还是加锁的顺序问题,现在的程序是固定的先锁定转账方在锁定收款方,由于用户身份的转变造成的加锁顺序不一致,可以在用户层面判断加锁顺序,比如根据用户id来判断加锁顺序而不是用户身份