JVisualVM 中线程状态(运行/休眠/等待/驻留/监视)解析
在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 中线程状态(运行/休眠/等待/驻留/监视)解析相关推荐
- android运行的线程中,android中线程是否运行在单独的进程中?
android sdk中的描述 Caution:A service runs in the main thread of its hosting process-the service doesnot ...
- c#: 线程状态和管理之线程的休眠、挂起和中断
环境: window 10 .NetFramework 4.7 vs2019 16.4.5 一.线程的状态 线程的状态可以从枚举ThreadState中查看到: public enum ThreadS ...
- Thread类源码解读(2)——线程状态及常用方法
上一篇我们讨论了线程的创建,本篇我们来聊一聊线程的状态转换以及常用的几个比较重要的方法. 本篇依然是通过源码分析来了解这些知识. 本文源码基于jdk1.8 . 阅读完本文,你应当有能力回答以下常见面试 ...
- Java基础加强重温_08:线程不安全、线程同步、线程状态、线程状态切换、线程池(Executors类、newFixedThreadPool)、死锁、Lambda表达式、Stream
摘要 Java基础加强重温_08: 线程安全(线程安全概念.线程不安全案例). 线程同步(同步代码块.同步方法.Lock锁,锁对象). 线程状态(new新建.Runnable可运行.Blocked锁阻 ...
- Java线程状态总结
目录 一.初始Java线程的所有状态 1.输出所有状态名 2.所有状态解释 3.线程的状态和转移图解 二.通过Java程序观察线程状态 1.isAlive()观察线程NEW,RUNNABLE,TERM ...
- windows线程状态
文章目录 线程状态 就绪态 备用态 运行态 等待态 转换态 终止态 线程关系 线程同步 线程互斥 实现同步与互斥方法 线程同步实例 未同步状态 使用临界区实现同步 使用事件实现同步 信号量 使用互斥量 ...
- 【线程】详解线程状态(到底是五种还是六种)
首先我们要知道,在传统(操作系统)的线程模型中线程被分为五种状态 在java线程中,线程被分为六种状态 传统线程模型(操作系统)中线程状态 线程的五种状态: 1.新建(new) ...
- python封装线程类(启动、终止、查看线程状态)
文章目录 一.简单说明 二.实现步骤 三.测试 一.简单说明 将启动.终止和查看线程状态的方法封装成类 声明时传入要启动的方法 通过 start.stop 和 state 执行启动.终止 和 查看状态 ...
- java中的锁池和等待池是什么_线程的几个状态及方法,等待池和锁池的理解
线程状态: 创建状态:创建一个线程实例 Thread thread = new Thread(); 就绪状态:在调用start()方法后,线程获取了除CPU的其他资源,处于就绪状态 执行状态:线程获取 ...
最新文章
- java多附件上传 实例demo
- 2.1.1进程的概念 组成和特征
- 搭建 Verilog 仿真环境
- C语言学习记录_2019.02.02
- java math round小数_Java——Math的round方法
- SpringCloud Ribbon(五)之服务实例列表ServerList
- 在保护继承中基类的共有成员_C++面向对象:C++ 继承
- .Net语言 APP开发平台——Smobiler学习日志:用Gridview控件设计较复杂的表单
- 判断当前是什么版本浏览器
- 麻省理工成立金融科技实验室,蚂蚁金服成唯一中国创始企业
- 文本挖掘学习笔记(二):文档信息向量化与主题关键词提取
- html中如何通过微信加朋友,微商必看:微信添加好友的13种方法和技巧
- Android 9.0系统源码_SystemUI(二)StatusBar系统状态栏的创建流程
- 损益科目不进行结转导致的对账问题
- ubuntu运行Openvino出现 ModuleNotFoundError: No module named ‘openvino.model_zoo.model_api‘解决
- node php知乎,基于jQuery和Bootstrap框架实现仿知乎前端动态列表效果
- ncl如何添加线shp文件_教程合集 | 地图数据找不到?家园都有解决方案!
- php是什么电荷,分子中电荷变化种种 - 量子化学 - 小木虫 - 学术 科研 互动社区...
- MySQL获取数据库元数据相关命令:DESC、SHOW、INFORMATION_SCHEMA、mysqlshow、mysqldump
- 20年吉林省综合测评