线程的状态 朱雀 2020-05-12 15:57 898阅读 0赞 # 线程的状态 一个Thread对象可以有多个状态,在`java.lang.Thread.State`中,总共定义六种状态: **1、NEW** 线程刚刚被创建,也就是已经new过了,但是还没有调用start()方法 **2、RUNNABLE** RUNNABLE这个名字很具有欺骗性,很容易让人误以为处于这个状态的线程正在运行。事实上,这个状态只是表示,线程是可运行的。我们已经无数次提到过,一个单核CPU在同一时刻,只能运行一个线程。 **3、BLOCKED** 线程处于阻塞状态,正在等待一个monitor lock。通常情况下,是因为本线程与其他线程公用了一个锁。其他在线程正在使用这个锁进入某个synchronized同步方法块或者方法,而本线程进入这个同步代码块也需要这个锁,最终导致本线程处于阻塞状态。 **4、WAITING** 等待状态,调用以下方法可能会导致一个线程处于等待状态: - `Object.wait` with no timeout - `Thread.join` with no timeout - `LockSupport.park` 例如:对于wait()方法,一个线程处于等待状态,通常是在等待其他线程完成某个操作。本线程调用某个对象的wait()方法,其他线程处于完成之后,调用同一个对象的notify或者notifyAll()方法。Object.wait()方法只能够在同步代码块中调用。调用了wait()方法后,会释放锁。 **5、TIMED_WAITING** 线程等待指定的时间,对于以下方法的调用,可能会导致线程处于这个状态: - `Thread.sleep` - `Object.wait` with timeout - `Thread.join` with timeout - `LockSupport.parkNanos` - `LockSupport.parkUntil` **6、TERMINATED** 线程终止。 这些状态中NEW状态是开始,TERMINATED时销毁,在整个线程对象的运行过程中,这个两个状态只能出现一次。其他任何状态都可以出现多次,彼此之间可以相互转换。 > Tips: > > 经常有人把线程的状态又称为线程的`生命周期`。个人认为这种叫法并不好,因为生命周期通常指的是一个对象从创建到销毁所必须要经历的过程。例如J2EE的Servlet的生命周期方法是init->service->destroy,这三个阶段是必须要经历的。而对于线程而言,完全可以NEW了之后就直接到TERMINATED了,或者只经历其中某个状态而不是所有。因此这可能也是官方只称之为线程状态(用java.lang.Thread.State类表示)的原因。不过,因为生命周期这个叫法在某种程度上又有一些说明力,笔者也不反对你也这样来称呼线程的不同状态。 > > 总之,需要知道的一点是,别人和你提到线程状态或者是线程生命周期,其实指的是同一个东西。 接下来,我们将通过`jps`,`jstack`工具演示说明线程的各个状态,首先我们准备一些测试代码: ```java public class ThreadState { public static void main(String[] args) { new Thread(new Running(), "RunningThread").start(); new Thread(new TimeWaiting(), "TimeWaitingThread").start(); new Thread(new Waiting(), "WaitingThread-1").start(); new Thread(new Waiting(), "WaitingThread-2").start(); // 使用两个Blocked线程,一个获取锁成功,另一个被阻塞 new Thread(new Blocked(), "BlockedThread-1").start(); new Thread(new Blocked(), "BlockedThread-2").start(); } /** * 表示线程正在运行 * @author dandelioncloud336 * */ static class Running implements Runnable{ @Override public void run() { for (int i = 0; i < Long.MAX_VALUE; i++) { i++; } } } /** * 该线程不断的进行睡眠 */ static class TimeWaiting implements Runnable { @Override public void run() { while (true) { SleepUtils.second(100); } } } /** * 该线程在Waiting.class实例上等待 */ static class Waiting implements Runnable { @Override public void run() { while (true) { synchronized (Waiting.class) { try { Waiting.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } /** * 该线程在Blocked.class实例上加锁后,不会释放该锁 */ static class Blocked implements Runnable { public void run() { synchronized (Blocked.class) { while (true) { SleepUtils.second(100); } } } } public static class SleepUtils { public static final void second(long seconds) { try { TimeUnit.SECONDS.sleep(seconds); } catch (InterruptedException e) { } } } } ``` 代码分析: `RunningThread`线程运行一个不断自增加法,持续时间会很长,线程一直应该处于RUNNABLE状态。 `TimeWaiting`线程里面是一个死循环,每次休眠100毫秒,因此大部分情况下,应该处于TIME-WAITING状态。 `WaitingThread-1`和`WaitingThread-2`共同竞争一个类锁:Waiting.class。而同步快里面,又调用了wait()方法,先得到锁的线程会释放锁,因此最终2个线程都处于Waiting状态。 `BlockedThread-1`和`BlockedThread-2`线程也是共同竞争一个类锁:Blocked.class。而同步快里面,是一个死循环,然后调用了SleepUtils.sleep()方法,因此一直不会释放锁。所以二者,应该是有一个大部分情况下处于Time-Waiting状态,另一个处于Blocked状态。 通过jps与jtack分析: ```shell C:\Users\dandelioncloud>jps 6240 ThreadState 6576 Jps 2568 org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar C:\Users\dandelioncloud>jstack 6240 >>1.txt ``` jps命令用户查看当前系统中运行的java进程。jstack工具用于追踪线程堆栈信息。上述操作,将线程堆栈信息输入1.txt文件中,在这个文件里,我们可以看到以下信息: ```shell "BlockedThread-2" #17 prio=5 os_prio=0 tid=0x14d90400 nid=0x1584 waiting on condition [0x15e7f000] java.lang.Thread.State: TIMED_WAITING (sleeping)//调用sleep方法导致的TIME-WAITING at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at chapter04.SleepUtils.second(SleepUtils.java:11) at chapter04.ThreadState$Blocked.run(ThreadState.java:91) - locked <0x048f1380> (a java.lang.Class for chapter04.ThreadState$Blocked) at java.lang.Thread.run(Thread.java:745) "BlockedThread-1" #16 prio=5 os_prio=0 tid=0x14d8ec00 nid=0x420 waiting for monitor entry [0x15cef000] java.lang.Thread.State: BLOCKED (on object monitor)//锁竞争导致的阻塞,在等待锁 at chapter04.ThreadState$Blocked.run(ThreadState.java:91) - waiting to lock <0x048f1380> (a java.lang.Class for chapter04.ThreadState$Blocked) at java.lang.Thread.run(Thread.java:745) "WaitingThread-2" #15 prio=5 os_prio=0 tid=0x14d7b800 nid=0x1bf8 in Object.wait() [0x15d4f000] java.lang.Thread.State: WAITING (on object monitor)//已经被锁住,但是还要再次获取,注意观察下面的locked紫色标记部分 at java.lang.Object.wait(Native Method) - waiting on <0x048efab0> (a java.lang.Class for chapter04.ThreadState$Waiting) at java.lang.Object.wait(Object.java:502) at chapter04.ThreadState$Waiting.run(ThreadState.java:75) - locked <0x048efab0> (a java.lang.Class for chapter04.ThreadState$Waiting) at java.lang.Thread.run(Thread.java:745) "WaitingThread-1" #14 prio=5 os_prio=0 tid=0x14d7b000 nid=0x18e4 in Object.wait() [0x15c6f000] java.lang.Thread.State: WAITING (on object monitor)//已经被锁住,但是还要再次获取 at java.lang.Object.wait(Native Method) - waiting on <0x048efab0> (a java.lang.Class for chapter04.ThreadState$Waiting) at java.lang.Object.wait(Object.java:502) at chapter04.ThreadState$Waiting.run(ThreadState.java:75) - locked <0x048efab0> (a java.lang.Class for chapter04.ThreadState$Waiting) at java.lang.Thread.run(Thread.java:745) "TimeWaitingThread" #13 prio=5 os_prio=0 tid=0x14d7a400 nid=0xc50 waiting on condition [0x15b9f000] java.lang.Thread.State: TIMED_WAITING (sleeping)//调用sleep方法导致的TIME-WAITING at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at chapter04.SleepUtils.second(SleepUtils.java:11) at chapter04.ThreadState$TimeWaiting.run(ThreadState.java:61) at java.lang.Thread.run(Thread.java:745) "RunningThread" #12 prio=5 os_prio=0 tid=0x14d79400 nid=0xa0c runnable [0x1596f000] java.lang.Thread.State: RUNNABLE //正常运行 at chapter04.ThreadState$Running.run(ThreadState.java:48) at java.lang.Thread.run(Thread.java:745) ``` 线程状态转换图 ![](/images/1589299005274.png)
相关 线程的状态 目录 1.线程状态的种类 2.线程的状态图 3.状态的详细说明 -------------------- 1.线程状态的种类 初始(NEW):新建一个线程,但还 落日映苍穹つ/ 2024年03月25日 20:08/ 0 赞/ 33 阅读
相关 线程状态和线程池状态 线程状态 有六种状态; 新创建(NEW) 可运行(Runnable) 锁阻塞(Blocked) 无线等待(Waiting) 计时等待(Timed Wa 桃扇骨/ 2023年10月06日 14:08/ 0 赞/ 17 阅读
相关 线程的状态 ![在这里插入图片描述][2d280b0176ba4be2ae9f37daba7f7c5d.gif_pic_center] 文章目录 一、线程的所有状态 二 ﹏ヽ暗。殇╰゛Y/ 2023年09月27日 13:09/ 0 赞/ 112 阅读
相关 线程的状态 我百度了一下,有说三种,有说四种,有说五种,有说六种,还有说七种。下边列出六种的说法,六种见的比较多。 这是线程的六种状态 1. 初始(NEW):新创建了一个线程对象, 墨蓝/ 2023年06月07日 05:37/ 0 赞/ 4 阅读
相关 线程的状态 线程的状态 在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于后面对Thread类中的方法的理解。 线程从创建到最终的消亡,要 Dear 丶/ 2022年09月24日 14:22/ 0 赞/ 171 阅读
相关 线程的状态 要想实现多线程,必须在主线程中创建新的线程对象。任何线程一般具有5种状态, 即 创建、就绪、运行、阻塞、终止。线程状态的转移与方法之间的关系如图所示 ![这里写图片描述][ 心已赠人/ 2022年07月21日 02:49/ 0 赞/ 203 阅读
相关 线程的状态 线程对象在不同的运行时期有不同的状态,状态信息就存在于State枚举类中, \ public static enum Thread.State extends En 秒速五厘米/ 2022年06月08日 00:46/ 0 赞/ 204 阅读
相关 线程的状态 Thread源码里定义了6种状态,如下: \ A thread state. A thread can be in one of the follo 川长思鸟来/ 2022年02月15日 13:47/ 0 赞/ 247 阅读
相关 线程的状态 线程共有六种状态 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9 妖狐艹你老母/ 2021年12月19日 00:21/ 0 赞/ 354 阅读
相关 线程的状态 RUNNABLE这个名字很具有欺骗性,很容易让人误以为处于这个状态的线程正在运行。事实上,这个状态只是表示,线程是可运行的。我们已经无数次提到过,一个单核CPU在同一时刻... 朱雀/ 2020年05月12日 15:57/ 0 赞/ 899 阅读
还没有评论,来说两句吧...