java 线程锁 jstack_JAVA线程状态梳理以及Jstack命令使用

1.先上一张线程状态转换图

bc68a217cb7411addc4f0b229ce5ea6b.png

做如下说明:代码中共有除RUNNING之外的6种状态,为了表示线程正在执行,特加了RUNNING这种状态。我们需要重点关注RUNNABLE、BLOCKED、WAITING和TIME_WAITING四种状态,jstack打印的线程堆栈中也会时时出现。

1)BLOCKED:很好理解,就是线程在等待获取锁进入同步块或者同步方法中。两个死锁的线程即是Blocked。

2)WAITING:比BLOCKED状态进步一些,指我已经获得锁了,但由于有些条件不满足,我自己等会,调用object.wait()方法。等条件满足了,别的线程调用notify再叫我。另外也可以调用Thread.join()方法,顾名思义就是调用别的线程的join方法,让别人join进来先执行,那我就只能等会了。但是由于wait()和notify()以及notifyAll()用于协调对共享资源的存取,所以必须在synchronized块中使用。所以即便wait状态的线程被notfiy唤醒了,也需要再次获得锁,所以唤醒后进入Blocked状态。

3)TIMED_WAITING:类比WAITING,差异是不需要notify()或者notifyAlL()方法唤醒,时间到了我自己醒了。另外sleep比较好理解,就是让当前线程睡一会,与wait的区别是它不释放锁。

4)RUNNABLE不用多说,在JAVA虚拟机中已经在运行,但是在等待操作系统资源,比如CPU时间片。

2.模拟一段死循环代码

public class NewTask2 implements Runnable{

@Override

public void run() {

while(true)

{

System.out.println("the thread name is:" + Thread.currentThread().getName());

}

}

}

public class DemoApplication {

public static void main(String[] args) throws Exception {

Thread t = new Thread(new NewTask2());

t.run();

}

}

3.运行main函数,查看任务管理器,找到PID,2284

23e3ab65675f73ec1ebe08f24a858182.png

4.使用Process Explorer工具,找到2284进程并查看属性。找到CPU占用最高线程TID,8840

13c85258dc45d4e3e3b61800262a10ad.png

5.将8840换算为16进制,即为2288,记下这个16进制数字

6.在cmd下执行jstack -l PID命令,即jstack -l 2284。可以看到nid=0x2288线程堆栈信息,线程状态为RUNNABLE和执行循环输出的代码行信息。另外也可以看到WAITING状态的线程

d3720c392b8e1c7dce6b3388101e9692.png

d88d3b070f753a4f7c59bcfb3e70e593.png

简单梳理了下线程状态转移流程并记录一下线程堆栈常用定位方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值