什么是死锁
死锁是指两个或者两个以上的进程在执行过程中,因抢夺资源而造成的一种互相等待的现象,若无外力干涉它们将都无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性也就很低,否则就会因争夺有限的资源而陷入死锁。
产生的条件
- 互斥:共享资源X和Y只能被一个线程占用
- 占有且等待:线程T1已经获取共享资源X,在等待共享资源Y的时候,不释放共享资源X
- 不可抢占:其他线程不能强行抢占线程T1占有的资源
- 循环等待:线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源,这就是循环等待。
死锁的例子
分析与解决
一般客户的生产环境没有JDK分析工具,只包含JRE的运行环境,所以可以准备一个相同版本的JDK即可。
在生成环境解压JDK,工具都在jdk的bin目录下
通过jps定位进程号
通过jstack查找死锁
如果实在Windows环境上可以使用JDK自带的分析工具JConsole去定位
死锁的预防
破坏占有且等待条件:保证一次申请所有的资源。
破坏不可抢占条件:synchronized无法做到,synchronized申请不到资源直接进入阻塞状态。
java.util.concurrent Lock可以解决此问题。
在JDK1.7以后,synchronized 已经得到的优化,性能已经不差于Lock锁了,所以也可以考虑使用synchronized关键字。
死锁的修复
如果不幸线上发生了死锁,那只能重启。只有修复程序本身才能根本的去解决死锁。避免死锁的产生条件发生。
