CPU100%和线程死锁都是形成系统运行缓慢、假死的缘由之一。这里讲解下若是发生这种状况如何定位。java
首先咱们给出以下代码模拟出CPU100%bash
public static void main(String[] args) {
cpuTest();
}
private static void cpuTest() {
new Thread(() -> {
while (true) {
new Object();
}
}, "CPU-100").start();
while (true) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
new Object();
long random = new Random().nextInt(200);
Thread.sleep(random);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
复制代码
咱们要模拟的场景是一个一直忙碌的死循环线程隐藏在众多线程之中。多线程
程序逻辑:启动一个不断执行的死循环线程命名为CPU-100,另外主线程每隔200毫秒启动10个线程。dom
执行top命令,找到java进程CPU总的使用率105.6%,进程id为22024spa
执行top -H -p 22024 查看该进程下全部线程的CPU使用率等状况。其中线程id为22041的CPU使用率99.9%。线程
执行jstack 22024 > stack.log,将该java进程的线程栈信息转储到stack.log3d
查看stack.log,能够查看当前线程信息,包括线程名、线程ID、方法、状态等。其中nid便是咱们前面找的线程id,只不过它以16进制展现。22041转16进制是0x5619 code
jstack能够查看线程状态,因此也能够定位死锁问题。cdn
首先咱们给出以下代码构造死锁,死锁线程分别命名为deadLock-一、deadLock-2blog
public static void main(String[] args) {
lockTest();
}
private static void lockTest() {
Object o1 = new Object();
Object o2 = new Object();
new Thread(() -> {
synchronized (o1) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println("deadLock-1");
}
}
},"deadLock-1").start();
new Thread(() -> {
synchronized (o2) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println("deadLock-2");
}
}
},"deadLock-2").start();
}
复制代码
jcmd 找到进程id 41579
jstack 41579,发现deadLock-1,deadLock-2线程都处于阻塞状态,最下面会直接给出死锁信息