面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?
摘要: 原创出处 https://studyidea.cn 「公众号:程序通事 」欢迎关注和转载,保留摘要,谢谢!
使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而让出 CPU 的执行权,直到数据读取完成。这个期间如果使用 jstack 查看线程状态,却可以发现Java 线程状态是处于 RUNNABLE,这就和上面说的存在矛盾,为什么会这样?
上面的矛盾其实是混淆了操作系统线程状态与 Java 线程状态。这里说的线程阻塞进入休眠状态,其实是操作系统层面线程实际状态。而我们使用 jstack 查看的线程状态却是 JVM 中的线程状态。
线程是操作系统中一种概念,Java 对其进行了封装,Java 线程本质上就是操作系统的中线程,其状态与操作系统的状态大致相同,但还是存在一些区别。
下面首先来看我们熟悉的 Java 线程状态。
Java 线程状态
Java 线程状态定义在 Thread.State
枚举中,使用 thread#getState
方法可以获取当前线程的状态。
Thread.State
状态如下图:
可以看到 Java 线程总共存在 6 中状态,分别为:
- NEW(初始状态)
- RUNNABLE(运行状态)
- BLOCKED(阻塞状态)
- WATTING(等待状态)
- TIMED_WAITING(限时等待状态)
- TERMINATED(终止状态)
NEW(初始状态)与 RUNNABLE(运行状态)
每个使用 new Thread()
刚创建出线程实例状态处于 NEW 状态,一旦调用 thread.start()
,线程状态将会变成 RUNNABLE。
RUNNABLE(运行状态) 与 BLOCKED(阻塞状态)
RUNNABLE 状态的线程在进入由 synchronized
修饰的方法或代码块前将会尝试获取一把隐式的排他锁,一旦获取不到,线程状态将会变成 BLOCKED,等待获取锁。一旦有其他线程释放这把锁,线程成功抢到该锁,线程状态就将会从 BLOCKED 转变为 RUNNABLE 状态。
RUNNABLE(运行状态) 与 WATTING(等待状态)
处于 WATTING 状态的线程将会一直处于无限期的等待状态,需要等待其他线程唤醒。总共存在三种方法将会使线程从 RUNNABLE 变成 WATTING。
Object#wait
线程在获取到 synchronized
隐式锁后,显示的调用 Object#wait()
方法。这种情况下该线程将会让出隐式锁,一旦其他线程获取到该锁,且调用了 Object.notify()
或object.notifyAll()
,线程将会唤醒,然后变成 RUNNABLE。
Thread#join
join
方法是一种线程同步方法。假设我们在 main 方法中执行 Thread A.join() 方法,main 线程状态就会变成 WATTING。直到 A 线程执行完毕,main 线程才会再变成 RUNNABLE。
LockSupport#park()
LockSupport 是 JDK 并发包里重要对象,很多锁的实现都依靠该对象。一旦调用 LockSupport#park()
,线程就将会变为 WATTING 状态。如果需要唤醒线程就需要调用 LockSupport#unpark,然后线程状态重新变为 RUNNABLE。
RUNNABLE(运行状态) 与 TIMED_WAITING(限时等待状态)
TIMED_WAITING 与 WATTING 功能一样,只不过前者增加限时等待的功能,一旦等待时间超时,线程状态自动变为 RUNNABLE。以下几种情况将会触发这种状态:
Thread#sleep(long millis)
- 占有 synchronized 隐式锁的线程调用
Object.wait (long timeout)
方法 Thread#join (long millis)
LockSupport#parkNanos (Object blocker, long deadline)
LockSupport#parkUntil (long deadline)
RUNNABLE(运行状态)与 TERMINATED(终止状态)
线程一旦执行结束或者线程执行过程发生异常且未正常捕获处理,状态都将会自动变成 TERMINATED。
Java 线程 6 种状态看起来挺复杂的,但其实上面 BLOCKED,WATTING,TIMED_WAITING,都会使线程处于休眠状态,所以我们将这三类都归类为休眠状态。这么分类的话,Java 线程生命周期就可以简化为下图:
通用操作系统线程状态
上面讲完 Java 系统的线程状态,我们来看下通用操作系统的线程状态。操作系统线程状态可以分为初始状态,可运行状态,运行状态,休眠状态以及终止状态,如下图:
这 5 中状态详细情况如下:
- 初始状态,这时候线程刚被创建,还不能分配 CPU 。
- 可运行状态,线程等待系统分配 CPU ,从而执行任务。
- 运行状态,操作系统将 CPU 分配给线程,线程执行任务。
- 休眠状态,运行状态下的线程如果调用阻塞 API,如阻塞方式读取文件, 线程状态就将变成休眠状态。这种情况下,线程将会让出 CPU 使用权。休眠结束,线程状态将会先变成可运行状态。
- 线程执行结束或者执行过程发生异常将会使线程进入终止状态,这个状态下线程使命已经结束。
对比两者线程状态
比较 Java 线程与操作系统线程,可以发现 Java 线程状态没有可运行状态。也就是说 Java 线程 RUNNABLE 状态包括了操作系统的可运行状态与运行状态。一个处于 RUNNABLE 状态 Java 线程,在操作系统层面状态可能为可运行状态,正在等待系统分配 CPU 使用权。
另外 Java 线程细分了操作系统休眠状态,分成了 BLOCKED,WATTING,TIMED_WAITING 三种。
当线程调用阻塞式 API,线程进入休眠状态,这里指的是操作系统层面的。从 JVM 层面,Java 线程状态依然处于 RUNNABLE 状态。JVM 并不关心操作系统线程实际状态。从 JVM 看来等待 CPU 使用权(操作系统线程状态为可运行状态)与等待 I/O (操作系统线程状态处于休眠状态)没有区别,都是在等待某种资源,所以都归入 RUNNABLE 状态。
其他 Java 线程状态与操作线程状态类似。
面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?
面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?相关推荐
- java runnable wait_面试官:都说阻塞 I/O 模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?...
摘要: 原创出处 https://studyidea.cn 「公众号:程序通事 」欢迎关注和转载,保留摘要,谢谢! 使用 Java 阻塞 I/O 模型读取数据,将会导致线程阻塞,线程将会进入休眠,从而 ...
- 「从源码中学习」面试官都不知道的Vue题目答案
前言 当回答面试官问及的Vue问题,我们除了照本宣科的回答外,其实还可以根据少量的源码来秀一把,来体现出你对Vue的深度了解. 本文会陆续更新,此次涉及以下问题: "new Vue()做了什 ...
- 程序员面试快手后感慨:你们经历过绝望吗?三个面试官都是清华的
一名程序员在面试完快手后如此感叹:快手的要求确实高,比阿里难进100倍,三个面试官都是清华的,全是问的acm和算法题. 所谓同行相轻,马上又网友评论:题刷得好不代表解决问题能力强,面试一般考一两个考察 ...
- 视频面试,面试官都在注意些什么?
受疫情的影响,"视频面试"功能成功解了企业避免"面对面"招聘的燃眉之急,也为求职者也带来了极大的便利. 随着视频面试的热度不断攀升,人们讨论的话题和热度自然也转 ...
- 面试官都在问 | Linux命令mpstat详解
面试官都在问 | Linux命令mpstat详解 1. mpstat的基本用法 mpstat的全称为Multiprocessor Statistics,是一款常用的多核CPU性能分析工具,用来实时查询 ...
- mysql怎么用_面试官都是这样发问的,连环冲锋炮,看你怎么抵挡(上)
本内容来源于和尚 16 年毕业的学长,先在 58,后阿里,如今准备跳槽了,以下内容为他的最近面试经历 我最近从大厂离职之后在合肥呆了个把月,之前已经准备了半个多月,从7月底开始投简历面试,目前是jav ...
- 阿里的面试官都喜欢问哪些问题?
作者:徐刘根 | 公众号:Java之间 金九银十是招聘的旺季,小编在这里也给大家整理了一套阿里面试官最喜欢问的问题或者出场率较高的面试题,助校招或者社招路上的你一臂之力! 首先我们需要明白一个事实,招 ...
- 吃透这JAVA并发十二核心,面试官都得对你刮目相看
1.HashMap 面试第一题必问的 HashMap,挺考验Javaer的基础功底的,别问为啥放在这,因为重要!HashMap具有如下特性: HashMap 的存取是没有顺序的. KV 均允许为 NU ...
- 面试不说点分布式的东西,面试官都有点看不起我呀
点击上方 Java后端,选择 设为星标 优质文章,及时送达 现在的面试和几年前的面试差距很大了,现在培训机构出来的同学很多都占一大部分,而且那张口要的可是真的有点多,甚至比一些工作两三年的朋友们还多, ...
- 关于逻辑回归,面试官都怎么问
作者 | Chilia 整理 | NewBeeNLP 最近准备开始如同考研一般的秋招复习了!感觉要复习的东西真的是浩如烟海;) 有2023届做算法的同学可以加入我们一起复习~ 关于BERT,面试官们都 ...
最新文章
- 面试被问分布式事务(2PC、3PC、TCC),这样解释没毛病!
- Please ensure JDK installation is valid and compatible with the current OS
- CreateProcess failed: The system cannot find the file specified.
- 二维树状数组 BZOJ 1452 [JSOI2009]Count
- 【EXLIBRIS】随笔记 006
- 专为linux设计的笔记本,平板变笔记本,Linux 设备也要凑凑热闹
- java学习笔记(4)
- 美货币政策突变给中国高房价…
- 华为徐直军:以持续创新加快数字化发展
- floatmap 二维数组_Golang学习笔记(四):array、slice、map
- visual studio 工具的使用
- LightGBM-GBDT-LR使用树集合进行特征转换
- javascript中常用的对象创建方式有哪些?
- windows命令行下ftp连接超时的可能原因
- C#实现自动升级(附源码)
- docker 集群swarm搭建
- 计算机中URL是指什么 ?
- python练习题:程序员问卷调查
- 小小一方士 C# Async\Await
- ​【​观察】云栖大会共话JDM模式 揭秘创新背后的价值和启示
热门文章
- 拓端tecdat|R语言样条曲线、分段线性回归模型piecewise regression估计个股beta值分析收益率数据
- 拓端tecdat|R平方/相关性取决于预测变量的方差
- python可以连接sql server_python连接sqlserver数据库之一
- abb机器人gsd文件_ABB机器人控制器死机故障维修
- 汉密尔顿路径(哈密顿路径)解析
- 2021-06-27循环控制 mapSet
- 2021-06-26初识JavaScript
- 计算机课程联合考试是什么意思,计算机技术在职研究生能否通过一月联考的方式学习课程内容...
- python怎么创建变量_创建一个新变量,它是python中另一个变量的...
- 小施同学的投资日记 开篇