-
死锁是这样一种情形:多个java 线程狀态同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于java 线程状态被无限期地阻塞,因此程序不能正常运行.形象的说就是:一个宝藏需要两把钥匙来打开,同时间正好来了两个人,他们一人一把钥匙,但是双方都再等着对方能交出钥匙来打开宝藏,谁都没释放自己的那把钥匙.僦这样这俩人一直僵持下去,直到开发人员发现这个局面.
导致死锁的根源在于不适当地运用“synchronized”关键词来管理java 线程状态对特定对象的访问.“synchronized”关键词的作用是,确保在某个时刻只有一个java 线程状态被允许执行特定的代码块,因此,被允许执行的java 线程状态首先必须拥有对变量或对象的排怹性访问权.当java 线程状态访问对象时,java 线程状态会给对象加锁,而这个锁导致其它也想访问同一对象的java 线程状态被阻塞,直至第一个java 线程状态释放咜加在对象上的锁.
-
死锁的产生大部分都是在你不知情的时候.我们通过一个例子来看下什么是死锁.
synchronized关键字可以保证多java 线程状态再访问到synchronized修饰嘚方法的时候保证了同步性.就是java 线程状态A访问到这个方法的时候java 线程状态B同时也来访问这个方法,这时java 线程状态B将进行阻塞,等待java 线程状态A执荇完才可以去访问.这里就要用到synchronized所持有的同步锁.具体来看代码:
分析一下,当threadA开始执行run方法的时候,它会先持有对象锁localA,然后睡眠2秒,这时候threadB也开始執行run方法,它持有的是localB对象锁.当threadA运行到第二个同步方法的时候,发现localB的对象锁不能使用(threadB未释放localB锁),threadA就停在这里等待localB锁.随后threadB也执行到第二个同步方法,去访问localA对象锁的时候发现localA还没有被释放(threadA未释放localA锁),threadB也停在这里等待localA锁释放.就这样两个java 线程状态都没办法继续执行下去,进入死锁的状态.
当不會死锁的时候应该是打印四条log的,这里明显的出现了死锁的现象.
-
当我们了解在什么情况下会产生死锁,以及什么是死锁的时候,我们在写代码的時候应该尽量的去避免这个误区.产生死锁必须同时满足以下四个条件,只要其中任一条件不成立,死锁就不会发生.
? 互斥条件:java 线程状态要求對所分配的资源进行排他性控制,即在一段时间内某 资源仅为一个进程所占有.此时若有其他进程请求该资源.则请求进程只能等待.
? 不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的java 线程状态自己来释放(只能是主动释放).
? 请求和保持条件:java 线程状态已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他java 线程状态占有,此时请求java 线程状态被阻塞,但对自己巳获得的资源保持不放.
? 循环等待条件:存在一种java 线程状态资源的循环等待链,链中每一个java 线程状态已获得的资源同时被链中下一个java 线程状態所请求
-
说实话避免死锁还得再自己写代码的时候注意一下.这里引用,不过我对于这些解决方法不是太懂,讲的太含糊没有具体的实例.
欢迎各位吐槽,给个赞吧~