jstack
命令详解可以参考大神的讲解:
https://www.cnblogs.com/flydean/p/jdk14-jvm-jstack.html
死循环
使用的大神的代码,jstack可以看到堆栈信息运行到哪里了,正好对应死循环里面的sleep,多次查看可以看到无法跳出死循环,如下:
import java.io.IOException;
import static java.lang.Thread.sleep;
/**
* @author Administrator
* @since 2021/1/23 22:31
*/
public class TestStack {
public static void test1(){
while (true){
System.out.println("time 1");
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
System.out.println("start");
test1();
//test2();
//test3();
System.out.println("end");
}
}
死锁
构造一个死锁,使用jstack查看信息,可以看到明显的锁住哪一个对象,等待哪一个对象,并且最后显示发现了一个死锁。
package com.example.mail.service;
import java.io.IOException;
import static java.lang.Thread.sleep;
/**
* @author Administrator
* @since 2021/1/23 22:31
*/
public class TestStack {
static Object o1 = new Object();
static Object o2 = new Object();
public static void test1(){
while (true){
System.out.println("time 1");
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void test2(){
new Thread(new Runnable() {
@Override
public void run() {
synchronized (o1){
System.out.println("thread1 lock o1");
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2){
System.out.println("thread1 lock 02");
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (o2){
System.out.println("thread2 lock o2");
try {
sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1){
System.out.println("thread2 lock 01");
}
}
}
}).start();
}
public static void main(String[] args) throws IOException {
System.out.println("start");
//test1();
test2();
//test3();
System.out.println("end");
}
}
等待输入
public static void test3() throws IOException {
System.in.read();
}
public static void main(String[] args) throws IOException {
System.out.println("start");
//test1();
//test2();
test3();
System.out.println("end");
}