如何使用jstack?线程的状态?
jstack的使用
文章目录
一、作用
二、语法
三、线程状态
a、如何查看pid进程内线程信息
b、线程的状态
一、作用
作用:用于显示指定进程内线程的信息
二、语法
jstack [option] <pid>
说明:
option:命令选项,常用选项如下:
-F:当’jstack [-l] pid’没有相应的时候强制打印栈信息,如果直接jstack无响应时,用于强制jstack),一般情况不需要使用
-l:长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表,会使得JVM停顿得长久得多(可能会差很多倍,比如普通的jstack可能几毫秒和一次GC没区别,加了-l 就是近一秒的时间),-l 建议不 要用。一般情况不需要使用
-m:打印java和native c/c++框架的所有栈信息.可以打印JVM的堆栈,显示上Native的栈帧,一般应用排查不需要使用
pid:进程id
三、线程状态
a、如何查看pid进程内线程信息
step1:获得进程的id,在这里获得eclipse的pid
点击Win+R,输入cmd,在该页面处输入jps,得到进程的pid,如下图所示:
step2:得到pid进程内线程信息
1、在eclipse运行如下代码:
package t;public class Test {public static void main(String[] args) {while(true) {}}
}
2、在cmd里面执行jstack pid命令,将得到的信息输入到outprint.txt里面,如下图所示:
3、打开outprint.txt查看pid进程内线程信息,部分信息如下:
2019-07-21 20:03:57 "Service Thread" #8 daemon prio=9 os_prio=0 tid=0x08272c00 nid=0x10fc runnable [0x00000000] 注:线程分为守护线程 (daemon) 和非守护线程 (non-daemon) 两种,通常都是守护线程;daemon 表示线程是否是守护线程 "C1 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0826c000 nid=0x914 waiting on condition [0x00000000] 注:prio:线程优先级 "Attach Listener" #6 daemon prio=5 os_prio=2 tid=0x08268400 nid=0x1c8c waiting on condition [0x00000000] 注:os_prio:该线程对应的操作系统线程的优先级 tid:Java中线程编号,JVM线程的id,JVM内部线程的唯一标识,通过 java.lang.Thread.getId()获取 "Signal Dispatcher" #5 daemon prio=9 os_prio=2 tid=0x08265c00 nid=0x3e4 runnable [0x00000000] 注:nid:即native id,该线程对应的操作系统中本地线程编号,每一个java线程都有一个对应的操作系统线程 "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x07bd5000 nid=0x1650 in Object.wait() [0x0893f000] 注:Finalizer:线程状态 WAITING (on object monitor):表示该线程处于等待状态,括号中的内容说明了导致等待的原因 "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x07bcdc00 nid=0x1f60 in Object.wait() [0x087ff000] |
b、线程的状态:
(1)、NEW:新创建了一个线程对象,但是还没有调用start()方法,jstack命令不会列出处于此状态的线程信 息。
(2)、RUNNABLE:线程对象调用了start()方法,就进入了就绪状态,RUNNABLE只是表示线程是可运行的,在等待其他获取CPU的使用权,因为进程中的多个线程之间采用抢占式独立运行,而一个单核CPU在同一时刻,只能运行一个线程,如以下例子所示:
package t;public class Test {public static void main(String[] args) {new TimeThread().start();new CounterThread().start();}}class TimeThread extends Thread{@Overridepublic void run() {while(true){System.out.println("时间线程~~~~~~~~~~~~~~~~~~");} }}class CounterThread extends Thread{@Overridepublic void run() {while(true){System.out.println("计数器线程*****************");}}}
代码运行结果:
由结果的不确定性,可以看线程是抢占式运行的,调用了start()方法,也不一定处于运行状态,要看是否获得CPU的执行权
(3)、BLOCKED:线程处于阻塞状态,正在等待一个监视器锁(monitor lock)。通常情况下,是因为本线程与其他线程公用了一个锁。其他在线程正在使用这个锁进入某个synchronized同步方法块或者方法,而本线程进入这个同步代码块也需要这个锁,最终导致本线程处于阻塞状态,例子:
Ⅰ、运行如下代码:
package t;public class Test {private static Object lock = new Object();public static void main(String[] args) {new Thread(new Task(), "线程1").start();new Thread(new Task(), "线程2").start();}static class Task implements Runnable {@Overridepublic void run() {synchronized (lock) {count();}}private void count() {while (true) {}}}
}
Ⅱ、执行jps命令获取进程id,如下图所示,100是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下
2019-07-21 23:44:10 //当前线程快照生成的时间 Full thread dump Java HotSpot(TM) Client VM (25.131-b11 mixed mode, sharing): "DestroyJavaVM" #10 prio=5 os_prio=0 tid=0x0262c000 nid=0x1768 waiting on condition [0x00000000] "线程2" #9 prio=5 os_prio=0 tid=0x14e06800 nid=0x200c waiting for monitor entry [0x157bf000] "线程1" #8 prio=5 os_prio=0 tid=0x14e06400 nid=0x21f0 runnable [0x1572f000] 由以上信息得:①线程1获取到锁,处于RUNNABLE状态; ②线程2处于BLOCK状态,处于"Entry Set"队列,等待monitor ③线程1、线程2共用一把锁 |
(4)、WAITING:等待状态,等待某个condition或monitor发生,调用以下方法可能会导致一个线程处于等待状态:
wait() 不指定超时时间,例子:
Ⅰ、运行如下代码:
package t;public class Test {public static void main(String[] args) {Object lock = new Object();synchronized (lock) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}
Ⅱ、执行jps命令获取进程id,如下图所示,9920是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下 :
2019-07-22 00:41:26 "main" #1 prio=5 os_prio=0 tid=0x0202c000 nid=0x2578 in Object.wait() [0x007cf000] 由以上信息得: ①、main线程先
特别说明: wait()和notify()一系列的方法,是属于对象的,不是属于线程的。它们用在线程同步时,synchronized语句块中
wait()意思是说,我等会儿再用这把锁,CPU也让给你们,我先休息一会儿! notify()意思是说,我用完了,你们谁用? 也就是说,wait()会让出对象锁,同时,当前线程休眠,等待被唤醒,如果不被唤醒,就一直等在那儿。 notify()并不会让当前线程休眠,但会唤醒休眠的线程。 |
join() 不指定超时时间,例子:
Ⅰ、运行如下代码:
public class Test {public static void main(String[] args) {CountThread countThread = new CountThread();//返回当前正在执行的线程对象countThread.start();try {countThread.join();} catch (InterruptedException e) {e.printStackTrace();}}static class CountThread extends Thread{@Overridepublic void run() {while(true) {}}}
}
Ⅱ、执行jps命令获取进程id,如下图所示9976是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下
"main" #1 prio=5 os_prio=0 tid=0x0287c000 nid=0x26d8 in Object.wait() [0x00ddf000] 特别说明:join方法:执行该方法的线程进入阻塞状态,直到调用该方法的线程结束后再由阻塞转为就绪状态,如图所示
|
park() 例子:
Ⅰ、运行如下代码:
import java.util.concurrent.locks.LockSupport;public class Test{public static void main(String[] args) {LockSupport.park();//禁用执行该行代码的线程。}
}
Ⅱ、执行jps命令获取进程id,如下图所示,9976是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下
"main" #1 prio=5 os_prio=0 tid=0x0072c000 nid=0x261c waiting on condition [0x0060f000] 特别说明: waiting on condition:等待资源,或等待某个条件的发生,出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。 |
(5)、TIMED_WAITING:线程等待指定的时间,对于以下方法的调用,可能会导致线程处于这个状态:
wait(long timeout) 指定超时时间,例子:
Ⅰ、运行如下代码:
package t;public class Test {public static void main(String[] args) {Object lock = new Object();synchronized (lock) {try {lock.wait(Long.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}}
}
Ⅱ、执行jps命令获取进程id,如下图所示,9200是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下
"main" #1 prio=5 os_prio=0 tid=0x024ec000 nid=0x217c in Object.wait() [0x0240f000] 特别说明:object.wait()与wait(long)的区别: object.wait()是属于类实例(Object及其子类实列,也包括Class类实例)的方法。 实现细节是把当前线程放入阻塞线程队列中,并把当前线程注册为指定对象的监听器,并锁释放指定对象的锁; 当被notify/notifyAll通知时,重新争取指定对象的锁,并把当前线程从指定对象的监听器中移除,把当前线程从阻塞队列放 入就绪队列,等待被调度。 而wait(long)方法阻塞时放入的是就绪队列,等待时间到期或被通知就可被调度,其他与wait()方法相同。 |
join(long millis) 指定超时时间,例子:
Ⅰ、运行如下代码:
public class Test {public static void main(String[] args) {CountThread countThread = new CountThread();countThread.start();try {countThread.join(Long.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}static class CountThread extends Thread{@Overridepublic void run() {while(true) {}}}
}
Ⅱ、执行jps命令获取进程id,如下图所示,4000是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下
"main" #1 prio=5 os_prio=0 tid=0x00c3c000 nid=0x1ddc in Object.wait() [0x00bef000] 从以上信息可知:join()、join(long millis)方法的实现都使用了wait方法 特别说明:join()、join(long millis) 假如在main线程中,调用thread.join方法,则main方法会等待thread线程执行完毕或者等待一定的时间。如果调用的是无 参join方法,则等待thread执行完毕,如果调用的是指定了时间参数的join方法,则等待一定的时间,不用等待thread执行 完毕 |
sleep(long millis) 指定超时时间,例子:
Ⅰ、运行如下代码:
public class Test {public static void main(String[] args) {try {Thread.sleep(Long.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}
}
Ⅱ、执行jps命令获取进程id,如下图所示,9648是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下
"main" #1 prio=5 os_prio=0 tid=0x0079c000 nid=0x25e8 waiting on condition [0x0081f000] 特别说明: sleep相当于让线程睡眠,交出CPU,让CPU去执行其他的任务。 但是sleep方法不会释放锁,也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个 对象 |
parkNanos(long nanos) 例子:
Ⅰ、运行如下代码:
import java.util.concurrent.locks.LockSupport;public class Test{public static void main(String[] args) {LockSupport.parkNanos(Long.MAX_VALUE);//在规定的截止时间(单位:纳秒,1毫秒=1,000,000纳秒)之前,执行该行代码的线程被禁用。}
}
Ⅱ、执行jps命令获取进程id,如下图所示,9596是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下
"main" #1 prio=5 os_prio=0 tid=0x025ac000 nid=0x2174 waiting on condition [0x00a0f000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338) at t.Test.main(Test.java:8) |
parkUntil(long deadline) 例子:
Ⅰ、运行如下代码:
import java.util.concurrent.locks.LockSupport;public class Test{public static void main(String[] args) {LockSupport.parkUntil(Long.MAX_VALUE);//在规定的截止时间(单位:毫秒)之前,执行该行代码的线程被禁用。}
}
Ⅱ、执行jps命令获取进程id,如下图所示,8580是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下
"main" #1 prio=5 os_prio=0 tid=0x007cc000 nid=0x135c waiting on condition [0x0077f000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338) at t.Test.main(Test.java:8) |
(6)、TERMINATED:线程终止。
死锁
Ⅰ、运行如下代码:
public class Test {// 创建两个线程之间竞争使用的对象private static Object lock1 = new Object();private static Object lock2 = new Object();public static void main(String[] args) {new ShareThread1().start();new ShareThread2().start();}static class ShareThread1 extends Thread {public void run() {synchronized (lock1) {try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2) {System.out.println("ShareThread1");}}}}static class ShareThread2 extends Thread {public void run() {synchronized (lock2) {try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock1) {System.out.println("ShareThread2");}}}}
}
Ⅱ、执行jps命令获取进程id,如下图所示,11064是我需要查看的进程的id:
Ⅲ、执行jstack pid命令,输入到out.txt文本里面,便于分析,如下所示:
Ⅳ、打开out.txt文本查看pid进程内线程信息,部分信息如下
Found one Java-level deadlock: Java stack information for the threads listed above: Found 1 deadlock. 特别说明: 如果有两个或两个以上的线程都访问了多个资源,而这些线程占用了一些资源的同时又在等待其它线程占用的资源,也就是 说多个线程之间都持有了对方所需的资源,而又相互等待对方释放的资源,在这种情况下就会出现死锁。 多个线程互相等待对方释放对象锁,此时就会出现死锁 |
如何使用jstack?线程的状态?相关推荐
- Java线程状态Jstack线程状态BLOCKED/TIMED_WAITING/WAITING解释
一.线程5种状态 新建状态(New) 新创建了一个线程对象. 就绪状态(Runnable) 线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运行,等待获 ...
- jstack 线程状态详解
jstack 线程状态详解 jatsck 用法 线程状态 一图以庇之 系统线程状态 (Native Thread Status) jatsck 用法 #jstack -h Usage:jstack [ ...
- Jstack线程状态BLOCKED/TIMED_WAITING/WAITING解释
一.线程5种状态 1.新建状态(New) 新创建了一个线程对象. 2.就绪状态(Runnable) 线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运行 ...
- jstack 线程状态
转自 http://www.cnblogs.com/nexiyi/p/java_thread_jstack.html jstack 线程状态 jstack 线程里,值得关注的线程状态有: 死锁,D ...
- java中线程的状态以及线程栈分析
java中线程的状态 状态 说明 NEW 初始状态.线程刚刚被创建,并且start()方法还未被调用 RUNNABLE 运行状态.表示线程正在java虚拟机中执行,但是可能正在等待操作系统的其他资源, ...
- 正确理解线程WAITING状态
正确理解线程WAITING状态 今天来学习下,Java的线程状态,重点讨论下thread.state.WAITING.讨论下线程如何进入此状态,以及它们之间的区别.最后,我们进一步了解java.uti ...
- 怎么查看线程的状态及interrupt优雅的关闭线程和interrupt()、interrupted()、isInterrupted()的作用以及区别在哪?
怎么查看线程状态 jps指令查看我当前的进程ID jstack 线程ID 示例: public class StatusDemo {public static void main(String[] a ...
- 线程的状态、调度、同步
线程的状态 java中的线程共五个状态:新建.就绪.运行.阻塞.死亡: 新建状态(New):处于系统创建线程,但未启动此线程,系统未为其分配资源. 就绪状态(Runnable):线程调用start( ...
- java线程的状态及状态间的切换
在 Java 5 以后,线程状态被明确定义在其公共内部枚举类型 java.lang.Thread.State 中. 分别是: 1. NEW(初始化状态) 2. RUNNAB ...
- JAVA线程六种状态_Java:线程的六种状态及转化
多线程概述及创建方式 Java:线程的六种状态及转化 关于线程的生命周期,网上书上说法不一,难以统一,本篇做一个总结: java.lang.Thread.State枚举类中定义了六种线程的状态,可以调 ...
最新文章
- 从数据集到2D和3D方法,一文概览目标检测领域进展
- WPF技术触屏上的应用系列(二): 嵌入百度地图、API调用及结合本地数据库在地图上进行自定义标点的实现...
- 分布式系统中处理参数配置的 4 种方案
- 假如,有这样的异性朋友真不错
- 单片机原理及其应用——单片机定时器中断实验(八段数码管依次显示0~9数字)
- 计算机408考研专题(建议收藏)
- java获取对象的子_java – 如何根据子对象字段获取父对象
- 项目Beta冲刺(团队1/7)
- 虚拟机Centos7连接Internet
- 第12章 数据库完整性
- 两万字 40 张图带你参透并发编程
- c++用向量给句子排序_用C ++对向量排序
- 关于Bean Validation
- Java 13新特性:switch表达式,文本块
- android ide 下载
- svn往分支提代码_[转]代码管理|svn分支管理
- 丝杠螺母传动机构设计
- 概率统计13——二项分布与多项分布
- Java企业汽车调度系统
- 【Hadoop实训】统计文件中所有单词的平均长度
热门文章
- SharePoint自动化系列——Set MMS field value using PowerShell.
- 宫崎峻《となりのトトロ》(龙猫)全剧本(中日对照)(2)
- Xcode中查看宏在预处理阶段的展开
- 特征工程一:特征缩放、选择
- python_文件处理模式
- Network 第三篇 - STP生成树协议
- 压缩解压打包工具基础
- 打造颠覆你想象中的高性能,轻量级的webform框架-----如何替换webform的垃圾控件(第一天)...
- Java 8 新特性:3-函数(Function)接口
- 菜鸟学自动化测试(八)----selenium 2.0环境搭建(基于maven)