1.先上一张线程状态转换图ide
作以下说明:代码中共有除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(); }
}spa
3.运行main函数,查看任务管理器,找到PID,2284操作系统
4.使用Process Explorer工具,找到2284进程并查看属性。找到CPU占用最高线程TID,8840线程
5.将8840换算为16进制,即为2288,记下这个16进制数字code
6.在cmd下执行jstack -l PID命令,即jstack -l 2284。能够看到nid=0x2288线程堆栈信息,线程状态为RUNNABLE和执行循环输出的代码行信息。另外也能够看到WAITING状态的线程进程
简单梳理了下线程状态转移流程并记录一下线程堆栈经常使用定位方法。ip