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
咱們搜索0x5619便可以定位到具體的線程,進而位到具體的程序代碼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線程都處於阻塞狀態,最下面會直接給出死鎖信息