注:以下代码讲解基于JDK1.8.0_144

一、线程状态分类

线程一共有六种状态,分别为New、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING

TERMINATED,同一时刻只有一种状态,通过线程的getState方法可以获取线程的状态。

二、线程状态讲解

2.1 NEW

/**

* Thread state for a thread which has not yet started.

*/

NEW,

当线程被创建出来还没有被调用start()时候的状态。

2.2 RUNNABLE

/**

* Thread state for a runnable thread.  A thread in the runnable

* state is executing in the Java virtual machine but it may

* be waiting for other resources from the operating system

* such as processor.

*/

RUNNABLE,

当线程被调用了start(),且处于等待操作系统分配资源(如CPU)、等待IO连接、正在运行状态,即表示Running状态和Ready状态。

注:不一定被调用了start()立刻会改变状态,还有一些准备工作,这个时候的状态是不确定的。

2.3 BLOCKED

/**

* Thread state for a thread blocked waiting for a monitor lock.

* A thread in the blocked state is waiting for a monitor lock

* to enter a synchronized block/method or

* reenter a synchronized block/method after calling

* {@link Object#wait() Object.wait}.

*/

BLOCKED,

等待监视锁,这个时候线程被操作系统挂起。当进入synchronized块/方法或者在调用wait()被唤醒/超时之后重新进入synchronized块/方法,锁被其它线程占有,这个时候被操作系统挂起,状态为阻塞状态。

阻塞状态的线程,即使调用interrupt()方法也不会改变其状态。

2.4 WAITING

/**

* Thread state for a waiting thread.

* A thread is in the waiting state due to calling one of the

* following methods:

* <ul>

*   <li>{@link Object#wait() Object.wait} with no timeout</li>

*   <li>{@link #join() Thread.join} with no timeout</li>

*   <li>{@link LockSupport#park() LockSupport.park}</li>

* </ul>

*

* <p>A thread in the waiting state is waiting for another thread to

* perform a particular action.

*

* For example, a thread that has called <tt>Object.wait()</tt>

* on an object is waiting for another thread to call

* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on

* that object. A thread that has called <tt>Thread.join()</tt>

* is waiting for a specified thread to terminate.

*/

WAITING,

无条件等待,当线程调用wait()/join()/LockSupport.park()不加超时时间的方法之后所处的状态,如果没有被唤醒或等待的线程没有结束,那么将一直等待,当前状态的线程不会被分配CPU资源和持有锁。

2.5 TIMED_WAITING

/**

* Thread state for a waiting thread with a specified waiting time.

* A thread is in the timed waiting state due to calling one of

* the following methods with a specified positive waiting time:

* <ul>

*   <li>{@link #sleep Thread.sleep}</li>

*   <li>{@link Object#wait(long) Object.wait} with timeout</li>

*   <li>{@link #join(long) Thread.join} with timeout</li>

*   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>

*   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>

* </ul>

*/

TIMED_WAITING,

有条件的等待,当线程调用sleep(睡眠时间)/wait(等待时间)/join(等待时间)/ LockSupport.parkNanos(等待时间)/LockSupport.parkUntil(等待时间)方法之后所处的状态,在指定的时间没有被唤醒或者等待线程没有结束,会被系统自动唤醒,正常退出。

2.6 TERMINATED

/**

* Thread state for a terminated thread.

* The thread has completed execution.

*/

TERMINATED;

执行完了run()方法。其实这只是Java语言级别的一种状态,在操作系统内部可能已经注销了相应的线程,或者将它复用给其他需要使用线程的请求,而在Java语言级别只是通过Java代码看到的线程状态而已。

三、状态转换图

四、常见场景

4.1 RUNNABLE状态

主要是测试在进入run方法之后线程的状态,以及在等待IO的时候,线程的状态。

测试代码:

public static void testStateRunnable() {IOThread simpleThread = new IOThread("IOThread");simpleThread.start();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Main thread check the state is " + simpleThread.getState() + "."); // RUNNABLE}static class IOThread extends Thread {public IOThread(String name) {super(name);}@Overridepublic void run() {System.out.println("In run method, state is " + getState() + "."); // RUNNABLESocket socket = new Socket();try {System.out.println("Try to connect socket address which not exist...");socket.connect(new InetSocketAddress(InetAddress.getByAddress(new byte[] { (byte) 192, (byte) 168, 1, 14 }), 5678));} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}

测试结果:

In run method, state is RUNNABLE.Try to connect socket address which not exist...Main thread check the state is RUNNABLE.

堆栈信息:

"IOThread" #10 prio=5 os_prio=0 tid=0x00000000187c7800 nid=0x8b0 runnable [0x00000000192ee000]java.lang.Thread.State: RUNNABLEat java.net.DualStackPlainSocketImpl.connect0(Native Method)at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)- locked <0x00000000eb6c0fa8> (a java.net.DualStackPlainSocketImpl)at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)at java.net.Socket.connect(Socket.java:589)at java.net.Socket.connect(Socket.java:538)at com.test.threadpool.TestThreadState$IOThread.run(TestThreadState.java:83)

4.2 BLOCKED状态

模拟两个线程抢锁,当一个线程抢到锁之后进入sleep,sleep状态下不会释放锁,所以另外一个线程被阻塞。从堆栈信息可以看到,locked和waiting to lock都是同一个对象。

测试代码:

 public static void testBlockedState() {Object lock = new Object();SleepThread t1 = new SleepThread("t1", lock);SleepThread t2 = new SleepThread("t2", lock);t1.start();t2.start();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread t1's state " + t1.getState());System.out.println("Thread t2's state " + t2.getState());}static class SleepThread extends Thread {private String name;private Object lock;public SleepThread(String name, Object lock) {super(name);this.name = name;this.lock = lock;}@Overridepublic void run() {System.out.println("Thread:" + name + " in run.");synchronized (lock) {System.out.println("Thread:" + name + " hold the lock.");try {Thread.sleep(1000 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread:" + name + " return the lock.");}}}

测试结果:

Thread:t2 in run.Thread:t1 in run.Thread:t2 hold the lock.Thread t1's state BLOCKEDThread t2's state TIMED_WAITING

堆栈信息:

"t2" #11 prio=5 os_prio=0 tid=0x0000000018604800 nid=0x934 waiting on condition [0x000000001920f000]java.lang.Thread.State: TIMED_WAITING (sleeping)at java.lang.Thread.sleep(Native Method)at com.test.threadpool.TestThreadState$SleepThread.run(TestThreadState.java:274)- locked <0x00000000eb64b910> (a java.lang.Object)
"t1" #10 prio=5 os_prio=0 tid=0x000000001860b000 nid=0x3528 waiting for monitor entry [0x000000001910f000]java.lang.Thread.State: BLOCKED (on object monitor)at com.test.threadpool.TestThreadState$SleepThread.run(TestThreadState.java:271)- waiting to lock <0x00000000eb64b910> (a java.lang.Object)

4.3 WAITING状态

4.3.1 调用wait()方法导致的WAITING状态。

测试代码:

 /*** 线程调用wait方法,状态变成WAITING。*/public static void testStateWatingByWait() {Object lock = new Object();WaitingThread waitingThread = new WaitingThread("WaitingThread", lock);waitingThread.start();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Main thread check the state is " + waitingThread.getState() + "."); // WAITING}static class WaitingThread extends Thread {private int timeout = 0;private Object lock;public WaitingThread(String name, Object lock) {this(name, lock, 0);}public WaitingThread(String name, Object lock, int timeout) {super(name);this.timeout = timeout;this.lock = lock;}@Overridepublic void run() {synchronized (lock) {if (timeout == 0) {try {System.out.println("Try to wait.");lock.wait();} catch (InterruptedException e) {e.printStackTrace();}} else {try {System.out.println("Try to wait in " + timeout + ".");lock.wait(timeout);} catch (InterruptedException e) {e.printStackTrace();}}}System.out.println("Over thread.");}}

测试结果:

Try to wait.Main thread check the state is WAITING.

堆栈信息:

"WaitingThread" #10 prio=5 os_prio=0 tid=0x0000000018dea000 nid=0x1220 in Object.wait() [0x00000000198ee000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x00000000eb6477e8> (a java.lang.Object)at java.lang.Object.wait(Object.java:502)at com.test.threadpool.TestThreadState$WaitingThread.run(TestThreadState.java:138)- locked <0x00000000eb6477e8> (a java.lang.Object)

4.3.2 调用join()方法导致的WAITING状态。

thread.join()方法其实就是synchronized(thread)内部一直判断thread的状态,如果为存活状态,就wait一个指定的时间,默认为0,然后继续循环判断,直到状态不为存活状态。

测试代码:

 /*** 线程调用join方法,状态变成WAITING。*/public static void testStateWatingByJoin() {Object lock = new Object();WaitingThread waitingThread = new WaitingThread("WaitingThread", lock);waitingThread.start();JoinThread joinThread = new JoinThread("JoinThread", waitingThread);joinThread.start();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Main thread check the join thread's state is " + joinThread.getState() + "."); // WAITING}static class JoinThread extends Thread {private int timeout = 0;private Thread thread;public JoinThread(String name, Thread thread) {this(name, thread, 0);}public JoinThread(String name, Thread thread, int timeout) {super(name);this.timeout = timeout;this.thread = thread;}@Overridepublic void run() {if (timeout == 0) {try {System.out.println("Try to join.");thread.join();} catch (InterruptedException e) {e.printStackTrace();}} else {try {System.out.println("Try to join in " + timeout + ".");thread.join(timeout);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("Over join.");}}static class WaitingThread extends Thread {private int timeout = 0;private Object lock;public WaitingThread(String name, Object lock) {this(name, lock, 0);}public WaitingThread(String name, Object lock, int timeout) {super(name);this.timeout = timeout;this.lock = lock;}@Overridepublic void run() {synchronized (lock) {if (timeout == 0) {try {System.out.println("Try to wait.");lock.wait();} catch (InterruptedException e) {e.printStackTrace();}} else {try {System.out.println("Try to wait in " + timeout + ".");lock.wait(timeout);} catch (InterruptedException e) {e.printStackTrace();}}}System.out.println("Over thread.");}}

测试结果:

Try to wait.Try to join.Main thread check the state is WAITING.

堆栈信息:

"JoinThread" #11 prio=5 os_prio=0 tid=0x0000000019007000 nid=0x33c0 in Object.wait() [0x0000000019c1f000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x00000000eb64a498> (a com.test.threadpool.TestThreadState$WaitingThread)at java.lang.Thread.join(Thread.java:1252)- locked <0x00000000eb64a498> (a com.test.threadpool.TestThreadState$WaitingThread)at java.lang.Thread.join(Thread.java:1326)at com.test.threadpool.TestThreadState$JoinThread.run(TestThreadState.java:194)
"WaitingThread" #10 prio=5 os_prio=0 tid=0x0000000019006000 nid=0x35ac in Object.wait() [0x0000000019b1f000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x00000000eb64a468> (a java.lang.Object)at java.lang.Object.wait(Object.java:502)at com.test.threadpool.TestThreadState$WaitingThread.run(TestThreadState.java:138)- locked <0x00000000eb64a468> (a java.lang.Object)

4.3.3 调用LockSupport.park方法导致的WAITING状态。

使用线程池的时候经常会遇到这种状态,当线程池里面的任务都执行完毕,会等待获取任务。

测试代码:

public static void testStateWatingByThreadExecutor() {ExecutorService executeService = Executors.newSingleThreadExecutor();executeService.submit(new Runnable() {@Overridepublic void run() {System.out.println("Over Run.");}});try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}

堆栈信息:

"pool-1-thread-1" #10 prio=5 os_prio=0 tid=0x0000000018f9c000 nid=0x2e88 waiting on condition [0x0000000019aaf000]java.lang.Thread.State: WAITING (parking)at sun.misc.Unsafe.park(Native Method)- parking to wait for  <0x00000000eb64cc30> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)

4.4 TIMED_WAITING状态

只测试sleep()方法,其余参照WAITING状态。

测试代码:

 public static void testSleep() {try {Thread.sleep(1000 * 100);} catch (InterruptedException e) {e.printStackTrace();}}

堆栈信息:

"main" #1 prio=5 os_prio=0 tid=0x0000000004f80800 nid=0x34bc waiting on condition [0x0000000004e7f000]java.lang.Thread.State: TIMED_WAITING (sleeping)at java.lang.Thread.sleep(Native Method)at com.test.threadpool.TestThreadState.testSleep(TestThreadState.java:233)at com.test.threadpool.TestThreadState.main(TestThreadState.java:53)

4.5 NEW和TERMINATED状态

测试创建线程,启动线程,线程运行完毕。处于这两个状态的线程在堆栈不会出现在堆栈信息里面。

测试代码:

public static void testNewAndTerminatedState() {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Over Run.");}});System.out.println("State " + thread.getState() + ".");thread.start();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("State " + thread.getState() + ".");}

测试结果:

State NEW.Over Run.State TERMINATED.

Java线程状态分析/线程状态转换图相关推荐

  1. 线程状态转换图及各部分介绍

    线程的状态转换图 线程的几种状态 新建状态(New): 用new语句创建的线程处于新建状态,此时它和其他Java对象一样,仅仅在堆区中被分配了内存. 就绪状态(Runnable): 当一个线程对象创建 ...

  2. 【Java 并发编程】线程池机制 ( 线程池状态分析 | 线程池状态转换 | RUNNING | SHUTDOWN | STOP | TIDYING | TERMINATED )

    文章目录 一.线程池状态分析 一.线程池状态分析 线程池的状态在 ThreadPoolExecutor 源码中定义 : private final AtomicInteger ctl = new At ...

  3. java线程池返回线程状态_Java线程的不同状态

    java线程池返回线程状态 介绍 在Java中,线程可以具有状态. Thread.State枚举定义Java线程可以具有的不同状态. 该枚举定义了以下值– 新 可运行 已封锁 等候 TIMED_WAI ...

  4. Java线程的不同状态

    介绍 在Java中,线程可以具有状态. Thread.State枚举定义Java线程可以具有的不同状态. 该枚举定义了以下值– 新 可运行 已封锁 等候 TIMED_WAITING 已终止 在接下来的 ...

  5. java 精灵线程_Java线程的状态分析

    /*** 线程的状态分析 *@authoraa **/ public classThreadState {public static void main(String[] args) throwsEx ...

  6. java 切换主线程_Java线程状态及切换、关闭线程的正确姿势分享

    前言 在讲线程之前有必要讨论一下进程的定义:进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位.进程实体由程序段, 数据段 PCB(进程控制块)组成.线程又是什么?线程可以 ...

  7. java线程6种状态转换,Java线程的生命周期和各种状态转换详解

    在Java中,任何对象都有生命周期,线程也不例外,它也有自己的生命周期.当Thread对象创建完成时,线程的生命周期便开始了,当线程任务中代码正常执行完毕或者线程抛出一个未捕获的异常(Exceptio ...

  8. 漫话:如何给女朋友解释为什么Java线程没有Running状态?

    在多线程操作系统中,通常是在一个进程中包括多个线程,每个线程都是作为利用CPU的基本单位,是花费最小开销的实体. 线程是有状态的,线程的状态被定义在Thread.State枚举中,在Java Doc中 ...

  9. Java中一个线程只有六个状态。至于阻塞、可运行、挂起状态都是人们为了便于理解,自己加上去的。...

    java中,线程的状态使用一个枚举类型来描述的.这个枚举一共有6个值: NEW(新建).RUNNABLE(运行).BLOCKED(锁池).TIMED_WAITING(定时等待).WAITING(等待) ...

  10. Java中的线程状态

    参考:https://my.oschina.net/goldenshaw?tab=newest&catalogId=3277710 1 线程状态 Java中的线程一共有6种状态. 在某个时刻, ...

最新文章

  1. Mysql如何创建短索引(前缀索引)
  2. JS详细入门教程(上)
  3. 云计算技术背后的天才程序员:Open VSwitch鼻祖Martin Casado
  4. v5系列服务器后面板不存在以下哪款指示,群晖RS10613xs+ NAS服务器后面板简介
  5. 魔兽争霸3地图(WarIII Maps):成神之路
  6. Java 数据字典的实现
  7. Android 源码查看网站分享
  8. dualbootpatcher下载_多系统软件Dual Boot Patcher教程(多图)
  9. 计算机操作系统版本号怎么查看,Windows系统版本怎么看?2种查看windows版本的方法介绍...
  10. 产品管理 OKR:最佳实践和示例
  11. 深度学习论文阅读图像分类篇(六):SENet《Squeeze-and-Excitation Networks》
  12. AD原理图设计中如何添加NET CLASS和差分线
  13. 渗透测试培训 末日实验室脚本检测演示教程
  14. 【正点原子Linux连载】第六十七章 Linux USB驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0
  15. LeetCode-179-最大数
  16. Jsp中分页功能的实现
  17. WPF的Prism框架简介
  18. ASP.NET.3.5揭秘
  19. JS实现视频弹幕效果
  20. 开源仿google plus的wordpress主题

热门文章

  1. Java架构师—PDMan数据库建模工具使用
  2. window10运行不了1stopt_1stopt点击运行没有反应求大佬指点
  3. 基于视觉SLAM的无人机仿真-px4-gazebo
  4. ODB++ 数据格式解析软件
  5. mdx 医学词典_一些西医学方面词典的介绍
  6. PCB封装绘制时的摆放方向
  7. python爬股票历史价格_【Python】利用ricequant获取上证指数以及所有股票历史价格数据...
  8. JavaWeb 登录实现图片验证码
  9. 网站的LOGO尺寸大小参考
  10. 隐马尔科夫链HMM详解