当前位置 : 主页 > 编程语言 > java >

使用 jstack 排查Java项目的Linux线上环境死锁

来源:互联网 收集:自由互联 发布时间:2022-07-05
死锁概念 两个或者两个以上的线程在执行的过程中,由于竞争资源或者由于彼此等待而造成线程阻塞,线程不再往下执行. 实战 准备项目 随便找个SpringBoot项目 package com . example . demo ; /*

死锁概念

两个或者两个以上的线程在执行的过程中,由于竞争资源或者由于彼此等待而造成线程阻塞,线程不再往下执行.

使用 jstack 排查Java项目的Linux线上环境死锁_linux

实战

准备项目

随便找个SpringBoot项目

package com.example.demo;

/**
*/
public class DeadLockTest extends Thread {

private String first;
private String second;
public DeadLockTest(String name, String first, String second) {
super(name);
this.first = first;
this.second = second;
}

public void run() {
synchronized (first) {
try {
System.out.println(this.getName() + " ...synchronized:===> first " + first);
Thread.sleep(1000L);
synchronized (second) {
System.out.println(this.getName() + " ...synchronized:===> second " + second);
}
} catch (InterruptedException e) {}
}
}
public static void main(String[] args) throws InterruptedException {
String lockA = "lockA";
String lockB = "lockB";
DeadLockTest t1 = new DeadLockTest("t1", lockA, lockB);
DeadLockTest t2 = new DeadLockTest("t2", lockB, lockA);
t1.start();
t2.start();
t1.join();
t2.join();
}


}package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {

public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}



@GetMapping("/hello")
public String c_ () throws InterruptedException {
String lockA = "lockA";
String lockB = "lockB";
DeadLockTest t1 = new DeadLockTest("t1", lockA, lockB);
DeadLockTest t2 = new DeadLockTest("t2", lockB, lockA);
t1.start();
t2.start();
t1.join();
t2.join();
return "你好";
}

}

打包部署

这个我就不演示了,将你自己的项目打包, 部署到 linux上,这个我就不演示了,大家都会.

访问网址

浏览器get请求敲击url: http://zjj101:8080/demo/hello ,发现浏览器一直在转圈圈,说明一直访问不通.

看tomcat日志发现已经是死锁状态了.

t1 ...synchronized:===> first lockA
t2 ...synchronized:===> first lockB

使用jstack工具

查看进程号

使用 ps -ef|grep java 命令查看到Java进程是11271

[root@zjj101 logs]# ps -ef|grep java
root 11271 1 3 09:45 pts/0 00:00:24 /usr/bin/java -Djava.util.logging.config.file=/root/apache-tomcat-8.5.28/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dignore.endorsed.dirs= -classpath /root/apache-tomcat-8.5.28/bin/bootstrap.jar:/root/apache-tomcat-8.5.28/bin/tomcat-juli.jar -Dcatalina.base=/root/apache-tomcat-8.5.28 -Dcatalina.home=/root/apache-tomcat-8.5.28 -Djava.io.tmpdir=/root/apache-tomcat-8.5.28/temp org.apache.catalina.startup.Bootstrap start

将日志导出到文件中

使用 jstack -l [进程号]>deadlock.jstack 命令将日志导出到deadlock.jstack文件中

[root@zjj101 logs]# jstack -l 11271 >deadlock.jstack
[root@zjj101 logs]# ls
catalina.2021-10-12.log localhost.2021-10-12.log
catalina.out localhost_access_log.2021-10-12.txt
deadlock.jstack manager.2021-10-12.log
host-manager.2021-10-12.log

查看日志文件

使用less命令查看,

敲击命令: less deadlock.jstack

然后打开文件一直翻,直到找到 "Found one Java-level deadlock:"字眼的东西,

然后看"Java stack information for the threads listed above:"下的内容, 上面说了两个线程在 DeadLockTest.java:21 行锁住了.

Found one Java-level deadlock:
=============================
"t2":
waiting to lock monitor 0x00007f61983ba9e8 (object 0x00000000e90f32c8, a java.lang.String),
which is held by "t1"
"t1":
waiting to lock monitor 0x00007f61983bfe78 (object 0x00000000e90f3300, a java.lang.String),
which is held by "t2"

Java stack information for the threads listed above:
===================================================
"t2":
at com.example.demo.DeadLockTest.run(DeadLockTest.java:21)
- waiting to lock <0x00000000e90f32c8> (a java.lang.String)
- locked <0x00000000e90f3300> (a java.lang.String)
"t1":
at com.example.demo.DeadLockTest.run(DeadLockTest.java:21)
- waiting to lock <0x00000000e90f3300> (a java.lang.String)
- locked <0x00000000e90f32c8> (a java.lang.String)

Found 1 deadlock.

查看你自己写的代码

发现的确是这里锁住了,然后你就去修改代码即可

使用 jstack 排查Java项目的Linux线上环境死锁_apache_02


上一篇:Java并发之的DelayQueue简单介绍和使用
下一篇:没有了
网友评论