在java自带的工具JVirtualVM中线程有以下几种状态:

先说结论,各状态含义如下,后面有详细的demo测试验证:

  • 运行(runnable):正在运行中的线程。

  • 休眠(timed_waiting):休眠线程,例如调用Thread.sleep方法。

  • 等待(waiting):等待唤醒的线程,可通过调用Object.wait方法获得这种状态,底层实现是基于对象头中的monitor对象

  • 驻留(waiting):等待唤醒的线程,和等待状态类似,只不过底层的实现方式不同,处于这种状态的例子有线程池中的空闲线程,等待获取reentrantLock锁的线程,调用了reentrantLock的condition的await方法的线程等等,底层实现是基于Unsafe类的park方法,在AQS中有大量的应用。

  • 监视(blocked):等待获取monitor锁的线程,例如等待进入synchronize代码块的线程。

代码测试

    private static final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();    private static final ReentrantLock reentrantLockTest = new ReentrantLock();    public static void main(String[] args) {        //基于println方法中的synchronize代码块测试运行或者监视线程Thread thread1 = new Thread(() -> {            while (true) {System.out.println("运行或者监视线程1");}}, "运行或者监视线程1");thread1.start();        //基于println方法中的synchronize代码块测试运行或者监视线程Thread thread2 = new Thread(() -> {            while (true) {System.out.println("运行或者监视线程2");}}, "运行或者监视线程2");thread2.start();        //monitor对象等待线程Object lock = new Object();        Thread thread3 = new Thread(() -> {            synchronized (lock) {                try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}, "等待线程synchronized");thread3.start();        //reentrantLock中的条件对象调用await方法线程为驻留线程ReentrantLock reentrantLock = new ReentrantLock();        Condition condition = reentrantLock.newCondition();        Thread thread4 = new Thread(() -> {reentrantLock.lock();            try {condition.await();} catch (InterruptedException e) {e.printStackTrace();} finally {reentrantLock.unlock();}}, "等待线程reentrantLock");thread4.start();        //休眠线程Thread thread5 = new Thread(() -> {            try {Thread.sleep(1000000);} catch (InterruptedException e) {e.printStackTrace();}}, "休眠线程");thread5.start();        Thread thread6 = new Thread(ThreadTest::lockMethod, "reentrantLock运行线程");thread6.start();        //等待获取reentrantLock的线程为驻留线程Thread thread7 = new Thread(() -> {            try {TimeUnit.MICROSECONDS.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}lockMethod();}, "reentrantLock监视线程");thread7.start();        //线程池中的空闲线程为驻留线程singleThreadExecutor.execute(() -> {            //线程池中的线程是懒加载,需要运行任务之后才会产生线程System.out.println("驻留线程运行");});}    private static void lockMethod() {reentrantLockTest.lock();        try {            while (true) {}} finally {reentrantLockTest.unlock();}}  //println源码也简单贴一下//java.io.PrintStream#println(java.lang.String)public void println(String x) {        //this表示System.out这个PrintStream对象synchronized (this) {print(x);newLine();}}

以上代码运行之后,打开JVirtualVM查看线程如下:

根据代码的顺序从上至下讲:

  • 两个运行或者监视线程的System.out.println()语句因为抢同一个synchronize锁,可以很明显的看出是在交替运行,状态分别处于运行监视状态。

  • 等待线程synchronize因为调用了Object的wait方法,一直处于等待状态。

  • 休眠线程省略。

  • 重点是和reentrantLock锁相关的三个线程,注意下上图中有一个地方写错了,等待线程reentrantLock,实际应该是驻留线程reentrantLock,可以看到无论是通过condition的await方法,还是在阻塞等待锁的过程中,都是处于驻留状态,而不是我一开始预想的等待状态,通过查看源码后发现它们最终都调用了Unsafe的park方法,后续的线程dump也能验证这一点。

  • pool- 1-threadpool-1就是那个线程池,因为里面的线程处于空闲状态,也属于驻留

线程dump

JVisualVM 中线程状态(运行/休眠/等待/驻留/监视)解析相关推荐

  1. android运行的线程中,android中线程是否运行在单独的进程中?

    android sdk中的描述 Caution:A service runs in the main thread of its hosting process-the service doesnot ...

  2. c#: 线程状态和管理之线程的休眠、挂起和中断

    环境: window 10 .NetFramework 4.7 vs2019 16.4.5 一.线程的状态 线程的状态可以从枚举ThreadState中查看到: public enum ThreadS ...

  3. Thread类源码解读(2)——线程状态及常用方法

    上一篇我们讨论了线程的创建,本篇我们来聊一聊线程的状态转换以及常用的几个比较重要的方法. 本篇依然是通过源码分析来了解这些知识. 本文源码基于jdk1.8 . 阅读完本文,你应当有能力回答以下常见面试 ...

  4. Java基础加强重温_08:线程不安全、线程同步、线程状态、线程状态切换、线程池(Executors类、newFixedThreadPool)、死锁、Lambda表达式、Stream

    摘要 Java基础加强重温_08: 线程安全(线程安全概念.线程不安全案例). 线程同步(同步代码块.同步方法.Lock锁,锁对象). 线程状态(new新建.Runnable可运行.Blocked锁阻 ...

  5. Java线程状态总结

    目录 一.初始Java线程的所有状态 1.输出所有状态名 2.所有状态解释 3.线程的状态和转移图解 二.通过Java程序观察线程状态 1.isAlive()观察线程NEW,RUNNABLE,TERM ...

  6. windows线程状态

    文章目录 线程状态 就绪态 备用态 运行态 等待态 转换态 终止态 线程关系 线程同步 线程互斥 实现同步与互斥方法 线程同步实例 未同步状态 使用临界区实现同步 使用事件实现同步 信号量 使用互斥量 ...

  7. 【线程】详解线程状态(到底是五种还是六种)

    首先我们要知道,在传统(操作系统)的线程模型中线程被分为五种状态 在java线程中,线程被分为六种状态 传统线程模型(操作系统)中线程状态 线程的五种状态:         1.新建(new)     ...

  8. python封装线程类(启动、终止、查看线程状态)

    文章目录 一.简单说明 二.实现步骤 三.测试 一.简单说明 将启动.终止和查看线程状态的方法封装成类 声明时传入要启动的方法 通过 start.stop 和 state 执行启动.终止 和 查看状态 ...

  9. java中的锁池和等待池是什么_线程的几个状态及方法,等待池和锁池的理解

    线程状态: 创建状态:创建一个线程实例 Thread thread = new Thread(); 就绪状态:在调用start()方法后,线程获取了除CPU的其他资源,处于就绪状态 执行状态:线程获取 ...

最新文章

  1. java多附件上传 实例demo
  2. 2.1.1进程的概念 组成和特征
  3. 搭建 Verilog 仿真环境
  4. C语言学习记录_2019.02.02
  5. java math round小数_Java——Math的round方法
  6. SpringCloud Ribbon(五)之服务实例列表ServerList
  7. 在保护继承中基类的共有成员_C++面向对象:C++ 继承
  8. .Net语言 APP开发平台——Smobiler学习日志:用Gridview控件设计较复杂的表单
  9. 判断当前是什么版本浏览器
  10. 麻省理工成立金融科技实验室,蚂蚁金服成唯一中国创始企业
  11. 文本挖掘学习笔记(二):文档信息向量化与主题关键词提取
  12. html中如何通过微信加朋友,微商必看:微信添加好友的13种方法和技巧
  13. Android 9.0系统源码_SystemUI(二)StatusBar系统状态栏的创建流程
  14. 损益科目不进行结转导致的对账问题
  15. ubuntu运行Openvino出现 ModuleNotFoundError: No module named ‘openvino.model_zoo.model_api‘解决
  16. node php知乎,基于jQuery和Bootstrap框架实现仿知乎前端动态列表效果
  17. ncl如何添加线shp文件_教程合集 | 地图数据找不到?家园都有解决方案!
  18. php是什么电荷,分子中电荷变化种种 - 量子化学 - 小木虫 - 学术 科研 互动社区...
  19. MySQL获取数据库元数据相关命令:DESC、SHOW、INFORMATION_SCHEMA、mysqlshow、mysqldump
  20. 20年吉林省综合测评

热门文章

  1. Oracle数据库多表连接查询操作以及查询操作的补充
  2. Flex Builder 3.0 开发环境
  3. 聊一聊 JavaScript 的一些奇葩知识
  4. hadoop与传统数据库的区别
  5. centos 7 下双网卡bond 与 trunk口的交换机通信(用作KVM虚拟机)
  6. 在ESG领域,区块链究竟怎么用?
  7. 孙子兵法(Unicode有的所有字都已录入,还有它字疑为误传)
  8. ckeditor 工具栏配置
  9. bilibili正在缓冲却无法播放
  10. 如何查看计算机网络密码是什么意思,电脑网络共享密码要怎么查找