java 线程状态 jstack_jstack查看jvm线程状态
有些時(shí)候我們需要查看下jvm中的線程執(zhí)行情況,比如,發(fā)現(xiàn)服務(wù)器的CPU的負(fù)載突然增
高了、出現(xiàn)了死鎖、死循環(huán)等,我們?cè)撊绾畏治瞿?#xff1f;
由于程序是正常運(yùn)行的,沒有任何的輸出,從日志方面也看不出什么問題,所以就需要
看下jvm的內(nèi)部線程的執(zhí)行情況,然后再進(jìn)行分析查找出原因。
用法:jstack
java線程的6種狀態(tài)
初始態(tài)(NEW)
創(chuàng)建一個(gè)Thread對(duì)象,但還未調(diào)用start()啟動(dòng)線程時(shí),線程處于初始態(tài)。
運(yùn)行態(tài)(RUNNABLE),在Java中,運(yùn)行態(tài)包括 就緒態(tài) 和 運(yùn)行態(tài)。
就緒態(tài)
該狀態(tài)下的線程已經(jīng)獲得執(zhí)行所需的所有資源,只要CPU分配執(zhí)行權(quán)就能運(yùn)行。
所有就緒態(tài)的線程存放在就緒隊(duì)列中。
運(yùn)行態(tài)
獲得CPU執(zhí)行權(quán),正在執(zhí)行的線程。
由于一個(gè)CPU同一時(shí)刻只能執(zhí)行一條線程,因此每個(gè)CPU每個(gè)時(shí)刻只有一條運(yùn)行態(tài)的線程。
阻塞態(tài)(BLOCKED)
當(dāng)一條正在執(zhí)行的線程請(qǐng)求某一資源失敗時(shí),就會(huì)進(jìn)入阻塞態(tài)。
而在Java中,阻塞態(tài)專指請(qǐng)求鎖失敗時(shí)進(jìn)入的狀態(tài)。
由一個(gè)阻塞隊(duì)列存放所有阻塞態(tài)的線程。
處于阻塞態(tài)的線程會(huì)不斷請(qǐng)求資源,一旦請(qǐng)求成功,就會(huì)進(jìn)入就緒隊(duì)列,等待執(zhí)行。
等待態(tài)(WAITING)
當(dāng)前線程中調(diào)用wait、join、park函數(shù)時(shí),當(dāng)前線程就會(huì)進(jìn)入等待態(tài)。
也有一個(gè)等待隊(duì)列存放所有等待態(tài)的線程。
線程處于等待態(tài)表示它需要等待其他線程的指示才能繼續(xù)運(yùn)行。
進(jìn)入等待態(tài)的線程會(huì)釋放CPU執(zhí)行權(quán),并釋放資源(如:鎖)
超時(shí)等待態(tài)(TIMED_WAITING)
當(dāng)運(yùn)行中的線程調(diào)用sleep(time)、wait、join、parkNanos、parkUntil時(shí),就會(huì)進(jìn)入該狀態(tài);它和等待態(tài)一樣,并不是因?yàn)檎?qǐng)求不到資源,而是主動(dòng)進(jìn)入,并且進(jìn)入后需要其他線程喚醒;
進(jìn)入該狀態(tài)后釋放CPU執(zhí)行權(quán) 和 占有的資源。
與等待態(tài)的區(qū)別:到了超時(shí)時(shí)間后自動(dòng)進(jìn)入阻塞隊(duì)列,開始競爭鎖。
終止態(tài)(TERMINATED)
線程執(zhí)行結(jié)束后的狀態(tài)。
使用jstack查找死鎖
構(gòu)造死鎖
public class TestDeadLock {
private static Object obj1 = new Object();
private static Object obj2 = new Object();
public static void main(String[] args) {
new Thread(new Thread1()).start();
new Thread(new Thread2()).start();
}
private static class Thread1 implements Runnable {
@Override
public void run() {
synchronized (obj1) {
System.out.println("Thread1 拿到了 obj1 的鎖!");
try {
// 停頓2秒的意義在于,讓Thread2線程拿到obj2的鎖 Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj2) {
System.out.println("Thread1 拿到了 obj2 的鎖!");
}
}
}
}
private static class Thread2 implements Runnable {
@Override
public void run() {
synchronized (obj2) {
System.out.println("Thread2 拿到了 obj2 的鎖!");
try {
// 停頓2秒的意義在于,讓Thread1線程拿到obj1的鎖 Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj1) {
System.out.println("Thread2 拿到了 obj1 的鎖!");
}
}
}
}
}
jstack 11464
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x0000017bfeca3e80 (object 0x000000008a0e36e8, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0000017bfeca5e80 (object 0x000000008a0e36f8, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at TestDeadLock$Thread2.run(TestDeadLock.java:40)
- waiting to lock <0x000000008a0e36e8> (a java.lang.Object)
- locked <0x000000008a0e36f8> (a java.lang.Object)
at java.lang.Thread.run(java.base@9.0.4/Thread.java:844)
"Thread-0":
at TestDeadLock$Thread1.run(TestDeadLock.java:22)
- waiting to lock <0x000000008a0e36f8> (a java.lang.Object)
- locked <0x000000008a0e36e8> (a java.lang.Object)
at java.lang.Thread.run(java.base@9.0.4/Thread.java:844)
Found 1 deadlock.
VisualVM工具的使用
打開 jdk1.8.0_211\bin\jvisualvm.exe
查看CPU、內(nèi)存、類、線程運(yùn)行信息
查看線程狀態(tài)
總結(jié)
以上是生活随笔為你收集整理的java 线程状态 jstack_jstack查看jvm线程状态的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: head()函数python_Pytho
- 下一篇: 来自Java空间的传送门