前言

很多文章说Java线程有五种状态:NEW(新建)、RUNNABLE(就绪)、RUNNING(运行)、BLOCKED(阻塞)、DEAD(死亡),而阻塞又分为等待阻塞、同步阻塞、其它阻塞。
很遗憾这种说法是错误的,这五种状态确实早期的进程状态,也就是单线程进程的状态。

线程状态

Java线程到底有几种状态,其实只要打开一下JDK源码,看一下java.lang.Thread类就知道了,java.lang.Thread定义了一个内部枚举java.lang.Thread.State,部分源码如下:

/*** A thread can be in only one state at a given point in time.* These states are virtual machine states which do not reflect* any operating system thread states.* 一个线程在特定的时刻,只能有一个状态。* 这些状态是虚拟机的状态,不能反映任何操作系统的线程状态* @since   1.5*/
public enum State {/*** Thread state for a thread which has not yet started.* 线程未开始的状态*/NEW,/*** 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.* 可运行的线程状态,此状态的线程正在JVM中运行,* 但也有可能在等待操作系统的其他资源,例如处理器*/RUNNABLE,/*** 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* 阻塞状态的线程在等待一个监视器锁去进入同步代码块/方法,* 或者调用后重新进入同步代码块/方法*/BLOCKED,/*** Thread state for a waiting thread.* A thread is in the waiting state due to calling one of the following methods:* Object.wait()* Thread.join()* LockSupport.park()* A thread in the waiting state is waiting for another thread to* perform a particular action.* 由于调用了Object.wait()、Thread.join()、LockSupport.park()其中一个方法,线程进入等待状态* 处于等待状态的线程,正在在等待另一个线程执行特定的操作*/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:* Thread.sleep()* Object.wait()* LockSupport.parkNanos()* LockSupport.parkUntil()* 有指定等待时间的线程等待状态* 由于调用了Thread.sleep(long)、Object.wait(long)、Thread.join(long)、* LockSupport.parkNanos(long)、LockSupport.parkUntil(long)其中一个方法并传入了正(数)时间参数,* 线程处于有时间限制的等待状态*/TIMED_WAITING,/*** Thread state for a terminated thread.* The thread has completed execution.* 线程已经执行完成,处于终止状态*/TERMINATED;
}

根据上述代码,可以知道Java线程有六个状态:NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(指定时间的等待)、TERMINATED(终止),线程之间的转换关系如下:

值得注意的是,Java线程是不区分Ready(就绪)和Running(运行)的,它们都是Runnable状态,我把他们画出来,是为了强调,也便于理解。

实例

  • 线程状态:NEW -> RUNNABLE -> TERMINATED

    public static void main(String[] args) throws Exception {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("执行run(),线程状态:" + Thread.currentThread().getState().toString());}});System.out.println("未调用start(),线程状态:" + thread.getState().toString());thread.start();// 睡眠1秒,让thread执行完成Thread.sleep(1000);System.out.println("线程执行完成,线程状态:" + thread.getState().toString());
    }
    

    执行结果

    未调用start(),线程状态:NEW
    执行run(),线程状态:RUNNABLE
    线程执行完成,线程状态:TERMINATED
    
  • 线程状态:NEW -> RUNNABLE -> TIMED_WAITING -> RUNNABLE -> TERMINATED
    public static void main(String[] args) throws Exception {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("执行run(),thread线程状态:" + Thread.currentThread().getState().toString());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("sleep结束,thread线程状态:" + Thread.currentThread().getState().toString());}});System.out.println("未调用start(),thread线程状态:" + thread.getState().toString());thread.start();// 睡眠200毫秒,让thread被调度起来,进入sleepThread.sleep(200);System.out.println("线程sleep,thread线程状态:" + thread.getState().toString());// 睡眠2秒,让thread执行完成Thread.sleep(2000);System.out.println("线程执行完成,thread线程状态:" + thread.getState().toString());
    }
    

    执行结果

    未调用start(),thread线程状态:NEW
    执行run(),thread线程状态:RUNNABLE
    线程sleep,thread线程状态:TIMED_WAITING
    sleep结束,thread线程状态:RUNNABLE
    线程执行完成,thread线程状态:TERMINATED
    
  • 线程状态:NEW -> RUNNABLE -> BLOCKED -> RUNNABLE -> TERMINATED
    private static Object lock = new Object();
    public static void main(String[] args) throws Exception {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("执行run(),thread线程状态:" + Thread.currentThread().getState().toString());synchronized(lock) {}System.out.println("synchronized结束,thread线程状态:" + Thread.currentThread().getState().toString());}});System.out.println("未调用start(),thread线程状态:" + thread.getState().toString());synchronized(lock) {thread.start();Thread.sleep(200);System.out.println("线程synchronized,thread线程状态:" + thread.getState().toString());}// 睡眠2秒,让thread执行完成Thread.sleep(2000);System.out.println("线程执行完成,thread线程状态:" + thread.getState().toString());
    }
    

    执行结果

    未调用start(),thread线程状态:NEW
    执行run(),thread线程状态:RUNNABLE
    线程synchronized,thread线程状态:BLOCKED
    synchronized结束,thread线程状态:RUNNABLE
    线程执行完成,thread线程状态:TERMINATED
    

总结

以上便是Java线程的六种状态,及其切换。

Java线程到底有几种状态相关推荐

  1. Java线程 Thread 的6种状态以及转变过程

    线程的6种状态以及转变: java的线程一共6种状态.具体代码见: java.lang.Thread.State 1 NEW 新建状态 Thread state for a thread which ...

  2. 面试:Java线程有哪几种状态,它们之间是如何切换的

    多线程历来是面试重灾区,有时对多线程的掌握程度决定了开发者的级别.想掌握多线程还是需要在实际工作中多应用. 而实际上经常用多线程开发的开发者并不多.但面试要问怎么办,只能是面向面试来学习.各个击破,事 ...

  3. Java并发编程一线程池的五种状态

    推荐:Java并发编程汇总 Java并发编程一线程池的五种状态 原文地址 Java多线程线程池(4)–线程池的五种状态 正文 线程池的5种状态:Running.ShutDown.Stop.Tidyin ...

  4. Java线程池--线程池的五种状态

    线程池的5种状态:Running.ShutDown.Stop.Tidying.Terminated. 线程池各个状态切换框架图: 1.RUNNING (1) 状态说明:线程池处在RUNNING状态时, ...

  5. Java中对象的三种状态

    转载自   Java中对象的三种状态 Java中的对象的三种状态是和垃圾回收紧密相关的,因此有必要深究. 状态一:可触及态:从根节点开始,可以搜索到这个对象,也就是可以访问到这个对象,也有人将其称为可 ...

  6. 线程及线程池的五种状态

    线程的5种状态 线程可以有如下5种状态:New .Runnable .Running .Blocked .Dead 状态之间的转换如图: 1.New (新创建) 当用new操作符创建一个线程时,如ne ...

  7. Java线程同步的几种方式

    Java线程同步的几种方式 1.使用synchronized关键字  它的工作是对同步的代码加锁,使得每一次只能有一个线程进入同步块,从而保证线程间的安全性.  synchronized关键字的用法: ...

  8. 线程池的五种状态及创建线程池的几种方式

    上篇<Java线程的6种状态详解及创建线程的4种方式> 前言:我们都知道,线程是稀有资源,系统频繁创建会很大程度上影响服务器的使用效率,如果不加以限制,很容易就会把服务器资源耗尽.所以,我 ...

  9. Java线程池的四种创建方式

    Java线程池的四种创建方式 Java使用Thread类来表示线程,所有的线程都是Thread类或者是他的子类.Java有四种方式来创建线程. (1)继承Thread类创建线程 (2)实现Runnab ...

最新文章

  1. JS中的call、apply、bind方法详解
  2. Android --- GridLayoutManager 设置了 item 均匀分布,但是无效
  3. Java获得泛型类中T的实例
  4. Crontab的格式
  5. 如何把linux电脑当做数据库,在linux下如何进行mysql命令行 创建数据库linux操作系统 -电脑资料...
  6. 如何设计第三方账号登陆?
  7. 18个不常见的C#关键字,您使用过几个?
  8. linux C/C++开发环境搭建指南
  9. python定义函数prime判断是否是素数_用自定义函数判断素数 用C语言编写自定义函数prime(int x),判断x是否为素数?...
  10. pandas plot label_数据科学| 手把手教你用 pandas 索引、汇总、处理缺失数据
  11. 田渊栋:博士五年总结
  12. java客户端程序用什么自动化测试_五大Java自动化测试框架
  13. mysql 语句中last_Mysql函数:Last_insert_id()语法讲解
  14. 【Java】JSON转EXCEL,支持多个数组生成多个sheet、附表头替换
  15. Ubuntu18.04安装GoldenDict词典【词库】
  16. linux java目录 语法_Linux 文件和目录的属性
  17. A股数据日级前复权数据补全
  18. Java循环综合练习四之日历打印
  19. Stripe 银行卡支付功能初步指南(Java)
  20. 聊一聊HTTPS双向认证的简单应用

热门文章

  1. html5语义化标签和属性实例,跟永哥学HTML5(6)H5语义化标记使用示例
  2. OBS使用流程问题总结
  3. JavaScript 实例
  4. 无盘读取服务器系统,无盘服务器系统
  5. 几个余数的定理和性质以及它们的应用
  6. 【微信小程序云开发】实现空闲教室管理系统设计
  7. 西安电子科技大学-EDA大作业-交通控制器
  8. 研究成果将会开源!复旦MOSS团队深度访谈来了
  9. 可以下载AR模型网站网址
  10. 【生物信息学-单细胞】什么是scATAC-seq