Java死锁检测定位分析大致流程
名词解释
死锁:多个线程(至少两个)在执行过程中,因互相争夺资源而造成的互相等待的现象!如无外力干涉,他们将无法推进!
死锁发生条件
-
请求保持: 进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
-
不可剥夺: 进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能是主动释放)。
-
相互等待: 等待持有资源的线程释放自己需要的资源。
-
互斥: 进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
web应用肯定是多线程的程序,它服务于多个请求,程序发生死锁后,死锁的线程处于等待状态(WAITING或TIMED_WAITING),等待状态的线程不占用cpu,消耗的内存也很有限,而表现上可能是请求没法进行,最后超时了。在死锁情况不多的时候,这种情况不容易被发现。
准备死锁场景:
/**
* @Author: Be.insighted
* Description:
* @date Create on 2020/8/29 10:56
**/
public class DeadLockTest {
private static Object object1 = new Object();
private static Object object2 = new Object();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
synchronized (object1) {
System.out.println("线程1获取object1锁...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (object2) {
System.out.println("线程1获取object2锁...");
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (object2) {
System.out.println("线程2获取object2锁...");
synchronized (object1) {
System.out.println("线程2获取object1锁...");
}
}
}
}).start();
System.out.println("main 线程执行完毕...");
}
}
死锁检测:
进入JDK安装目录的bin目录下,如:C:\Program Files\Java\jdk1.8.0_45\bin
利用JDK自带工具 jps.exe & jstack.exe分析
一共三个步骤! 主要是利用工具!!!
第一步:cmd回车
第二步: 输入jps 回车 找到对应进程号
第三步: 输入 jstack -l 22864
Found one Java-level deadlock: