背景

先来探讨一个关于多线程的基础知识:java线程有多少种状态?根据JDK定义,答案是六种!为什么很多人给出的答案却是五种呢?这极有可能是将操作系统层面的线程状态和java线程状态混为一潭了。因为,小编在翻阅JDK源码的基础上,介绍一下java线程的六种状态以及操作系统层面的五种状态。

java线程状态

JDK中声明了六种java线程状态,以枚举的形式定义在Thread.State中,而且注释开篇撇清了和操作系统层面线程状态的关系-----【这些是状态是虚拟机状态,不反映任何操作系统的线程状态】,英文原文描述如下:

简单来介绍一下这六种状态。

1.new:新建状态,新创建一个线程对象时的初始状态,此时尚未调用start()方法。

2.runnable:就绪状态,Java线程把操作系统中的就绪和运行两种状态统一称为“就绪状态或者可运行状态”。英文相关描述如下:

A thread in the runable state is executing in the Java virtual machine but it may be waiting for other resources from the operation system such as processor.

线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu的使用权。

3.blocked: 阻塞状态,表示线程进入等待状态,也就是线程因为某种原因放弃了CPU使用权,阻塞也分为几种情况:

  • 等待阻塞:运行的线程执行了Thread.sleep,Object.wait(),join()等方法,JVM会把当前线程设置为等待状态,当sleep结束,join线程终止或者线程被唤醒后,该线程从等待状态进入阻塞状态,重新抢占锁后进行线程恢复。
  • 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被其他线程占用了,那么JVM会把当前的线程放入到锁池中。
  • 其他阻塞:发出了I/O请求时,JVM会把当前线程设置为阻塞状态,当I/O处理完毕则线程恢复。

4. waiting: 等待时间,没有超过时间,要被其他线程或者有其他的中断操作;即一个正在无限期等待另一个线程执行一个特别的动作的线程处于waiting状态,英文原文如下:

A thread that is waiting indefinitely for another thread to perform a particular action is in the state.

一个线程进入waiting 状态是因为调用了方法Object.wait(),Thread.join()或者LockSupport.park()。然后会等其他线程执行一个特别的动作,比如:

  • 一个调用了Thread.join方法的线程会等待指定的线程结束。
  • 一个调用了某个对象的wait方法的线程会等待另一个线程调用此对象的notify()或notifyAll()。

5.Time_waiting:等待超时,超过以后会自动返回;如下方执行超时,就会进入超时等待状态:Thread.sleep(long),Object.wait(long),Thread.join(long),LockSupport.park(long),LockSupport.parkNanos(long),LockSupport.parkUntil(long)。

6. Terminated:终止状态,表示当前线程执行完毕。

我们可以通过getState()来查看线程的当前状态:

线程状态间的转换

借一个图来描述:

关于具体的转换场景,图中描述的比较清楚,此处不在赘述。注意:

  1. sleep,join,yieId时并不释放对象锁资源,而执行函数wait()时会释放锁,对象在被notif/notifyAll唤醒时,重新去抢夺获取对象锁资源。
  2. sleep可以在任何地方使用,而wait,notify,notifyAll只能在同步方法或者同步块中使用。
  3. 调用obj.wait()会立即释放锁,以便其他线程可以执行notify,但notify()不会立刻释放sycronized(obj)中的对象锁,必须要等notify()所在线程执行完同步方法或者同步块才会释放这把锁,然后供线程等待池的线程来抢夺对象锁。 wait方法是Object的方法,线程释放锁,进入waiting或timed_waitind 状态,等待时间到了或被 notif/notifyAll唤醒后回去竞争锁,如果获得锁,进入runnable,否则进入阻塞状态等待获取锁。

操作系统层面线程状态

很多人会把操作系统层面的线程状态与java线程状态混淆,所以导致有的文章中把java线程状态写成5种,在此我们说清楚一个问题,java线程状态是6个,操作系统层的线程是5种,如下图所示:

下面分别介绍一下这五种状态:

  1. new :一个新的线程被创建,等待该线程被调用执行。
  2. ready:表示线程已被创建,正在等待系统调度分配CPU使用权或者时间片已用完,此线程被强制暂停,等待下一个属于它的时间片到来。
  3. running:表示线程获得了CPU使用权,正在占用时间片。
  4. waiting:表示线程等待(或者说挂起),等待某一事件(如IO或另一个线程)执行完,让出CPU资源给其他线程使用。
  5. terminated:一个线程完成任务或者其他终止条件发生,该线程终止进入退出状态,退出状态释放该线程所分配的资源。

需要注意的是:操作系统中的线程除去new和terminated状态,一个线程真实存在的状态是ready,running和waiting。

Thread.State中的Runnable状态涵盖了操作系统层面的【可运行状态】,【运行状态】和【阻塞状态】(由于BIO导致的线程阻塞,在java里无法区分,仍然认为是可运行,就好比我们在run()方法里调用IO方法,再者虽然有线程上下文切换但在JAVA层面还是运行的)。

至此,我们就把java线程状态以及操作系统层面的线程就理清了,喜欢的小伙伴可以关注我呀

java线程状态和状态切换相关推荐

  1. 面试官问:为什么 Java 线程没有 Running 状态?我懵了

    转载自 面试官问:为什么 Java 线程没有 Running 状态?我懵了 什么是 RUNNABLE? 与传统的ready状态的区别 与传统的running状态的区别 当I/O阻塞时 如何看待RUNN ...

  2. 面试官问:为什么 Java 线程没有Running状态?我懵了

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 title: 面 ...

  3. java 切换panel会闪烁_【19期】为什么Java线程没有Running状态?

    Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事.具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 State 这一内部枚举类中所定义的状态: 什么 ...

  4. 面试:为什么 Java 线程没有Running状态?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源 | my.oschina.net/goldenshaw/bl ...

  5. 为什么 Java 线程没有 Running 状态?一下被问懵!

    什么是 RUNNABLE? 与传统的ready状态的区别 与传统的running状态的区别 当I/O阻塞时 如何看待RUNNABLE状态? Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状 ...

  6. 为什么 Java 线程没有 Running 状态?

    Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事.具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 State 这一内部枚举类中所定义的状态: 什么 ...

  7. java 线程状态_面试官问:为什么Java线程没有Running状态?我懵了

    点击上方"占小狼的博客",选择"设为星标" 本文阅读时间大约4分钟. 来源:https://dwz.cn/dLRLBZab Java虚拟机层面所暴露给我们的状态 ...

  8. java 线程状态_【19期】为什么Java线程没有Running状态?

    Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事.具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 State 这一内部枚举类中所定义的状态: 什么 ...

  9. java线程四种状态

    一个线程可以有四种状态: 1.新(new), 即线程刚刚创建,而并未执行 2.可运行(runnable),意味着一旦时间分片机制有空闲的CPU周期提供给一个线程,那个线程便可立即开始运行.因此,线程可 ...

  10. Java线程6个状态详解

    文章目录 1. 概述 2. 举例说明 2.1 NEW 2.2 RUNNABLE 2.3 BLOCKED 2.4 WAITING 2.5 TIMED_WAITING 2.6 TERMINATED 1. ...

最新文章

  1. 巨杉数据库中标东莞农商银行非结构化内容管理平台项目
  2. 科幻作文计算机,种子科幻作文
  3. guid主分区表损坏怎么办_轻钢龙骨隔墙怎么办?轻钢龙骨隔墙的做法
  4. 2021年第3周人工智能方向的周报
  5. 单页面二改套后台,后台采用的是迅睿CMS框架
  6. Flutter ScrollController not attached to any scroll views 异常
  7. 区块链学习笔记:D03 区块链在各行业领域的应用(一)
  8. iPhone 13或将配备更大容量电池 售价与iPhone 12基本相当
  9. ac3168无线网卡驱动下载_计算机基础:网卡
  10. android 连线题实现 自定义view  画线
  11. python 克里金空间插值_空间插值——克里金插值
  12. 你知道硬齿面减速机价格为什么比齿轮减速机,蜗轮蜗杆减速机高?
  13. java使用poi导出excel 包括多个工作簿
  14. BGP多线和双线双IP服务器有什么区别? 哪个网站访问速度更快?
  15. iPhone检测是否存在耳麦
  16. 男人,就要对自己下手狠一点
  17. ES应用场景及核心概念一
  18. CGLIb 创建代理
  19. Linux-hostname查看及修改
  20. MSBUILD : error MSB4132: The tools version “2.0“ is unrecognized. Available tools versions are “4.0“

热门文章

  1. 栈和队列、堆、堆栈的区别?
  2. 使用DpInst安装驱动程序
  3. 查看linux文件生成时间,【linux】如何查看文件的创建、修改时间
  4. (一)ArcGIS空间数据的转换与处理——投影变换
  5. linux 下 `dirname $0`
  6. C# -> (Cshape)笔记
  7. STM32例程分享-01-OLED模块(IIC)
  8. mysql全备和指定库和表备份,mysql日志的分类简介和作用, mysql加速跳过域名解析,mysql权限授予与收回,数据库实用篇~~Tring
  9. c++中的继承机制(Derived Classes)
  10. C++ define用法