热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java线程状态分析/线程状态转换图

注:以下代码讲解基于JDK1.8.0_144一、线程状态分类线程一共有六种状态,分别为New、RUNNABLE、BLOCKED、WAITING、TI

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


一、线程状态分类
 

线程一共有六种状态,分别为NewRUNNABLEBLOCKEDWAITINGTIMED_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:

         *

             *   

  • {@link Object#wait() Object.wait} with no timeout
  •          *   

  • {@link #join() Thread.join} with no timeout
  •          *   

  • {@link LockSupport#park() LockSupport.park}
  •          *

         *

         *

A thread in the waiting state is waiting for another thread to

         * perform a particular action.

         *

         * For example, a thread that has called Object.wait()

         * on an object is waiting for another thread to call

         * Object.notify() or Object.notifyAll() on

         * that object. A thread that has called Thread.join()

         * 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:

         *

             *   

  • {@link #sleep Thread.sleep}
  •          *   

  • {@link Object#wait(long) Object.wait} with timeout
  •          *   

  • {@link #join(long) Thread.join} with timeout
  •          *   

  • {@link LockSupport#parkNanos LockSupport.parkNanos}
  •          *   

  • {@link LockSupport#parkUntil LockSupport.parkUntil}
  •          *

         */

        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状态

模拟两个线程抢锁,当一个线程抢到锁之后进入sleepsleep状态下不会释放锁,所以另外一个线程被阻塞。从堆栈信息可以看到,lockedwaiting 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&#39;s state " + t1.getState());System.out.println("Thread t2&#39;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&#39;s state BLOCKEDThread t2&#39;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&#39;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 NEWTERMINATED状态

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

测试代码:

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.

推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
author-avatar
曾明铭智瑜淑岳
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有