【Java笔记】多线程0:JVM线程是用户态还是内核态?Java 线程与OS线程的联系

文章目录

  • JVM线程是用户态线程还是内核态线程
    • 什么是用户态线程与内核态线程
    • 绿色线程
      • 绿色线程的缺点
    • 线程映射
      • 稍微回顾下线程映射模型
      • JVM线程映射
  • 线程状态
    • 操作系统的线程状态
    • JVM的线程状态
    • JVM线程与OS线程的状态关系
  • Reference

今天复盘一下Java中,JVM线程与实际操作系统中线程的一些联系
请先思考下面问题:

JVM线程是用户态线程还是内核态线程

什么是用户态线程与内核态线程

先简单回顾下几个概念:

用户线程(User Thread):在用户空间实现的线程,不是由内核管理的线程,是由用户态的线程库来完成线程的管理;
内核线程(Kernel Thread):在内核中实现的线程,是由内核管理的线程

可能有朋友觉得,Java线程都是我们用户new出来的,应该是用户态吧?
这种感觉肯定是错的,因为用户也可以完成一些内核态操作,比如通过命令行来进行命令调用与shell脚本。

先说一下结论:早期Java的“绿色线程”是用户态线程,现在则是通过1:1线程映射模型映射到内核态线程。

绿色线程

在古早版本中(jdk1.2之前),Java的一个特大卖点就是跨平台特性,也就是那个经典口号:“Write once, run anywhere”。但那个时候有些平台还没提供本地线程的支持,无法将用户线程映射到OS线程。所以那会采用的是“绿色线程”(Green Threads),也就是在虚拟平台上模拟出“内核线程”。

而绿色线程运行在用户空间,通过第三方library或者VM进行调度,可以说属于用户态线程

绿色线程的缺点

前面说了,绿色线程无法将用户线程映射为内核线程,只是在用户空间的模拟,对于造作系统来说都属于一个进程,仅有一个并发的概念,不能发挥多核CPU的优势去实现真正并行

线程映射

稍微回顾下线程映射模型

用户态线程是可以准备好程序让内核态线程执行,因此需要一些模型来实现用户线程和内核线程的对应关系:

  • One to One:一个用户线程对应一个内核线程,一旦用户线程停止,两个线程都会离开OS
    • 缺点:
      • 操作系统限制了内核线程的数量
      • 操作系统内核线程调度时,上下文切换的开销较大(相比于其他映射模型),导致用户线程的执行效率下降
  • Many to One:多个用户线程对应一个内核线程,用户线程间的切换由用户态代码实现
    • 优点:相对一对一模型,多对一模型的线程切换速度要快许多,并且数量不受OS内核线程数的影响
    • 缺点:
      • 如果其中一个用户线程阻塞,时内核线程也随之阻塞,其他用户线程也无法执行
      • 在多处理器系统上,处理器数量的增加对多对一模型的线程性能不会有明显的增加,因为所有的用户线程都映射到一个处理器上了
  • Many to Many:多个用户线程对应到多个内核线程,内核线程数M可以小于用户态线程数N
    • 优点:(解决了前两个的缺点)
      • 一个用户线程的阻塞不会导致所有线程的阻塞
      • 对用户线程的数量没有限制,
      • 在多处理器的操作系统中,多对多模型的线程也能得到一定的性能提升,但提升的幅度不如一对一模型的高

JVM线程映射

由于绿色线程仅仅是线程概念的用户态模拟,不能并行,因此后来换成了映射的方式来将JVM线程映射到OS内核线程。

现在,每个Java线程都映射到操作系统中一个完全独立的线程(一般是One to One),其创建销毁等工作都通过内核操作完成。

线程状态

操作系统的线程状态

操作系统的线程可描述为五种状态:new、ready、run、block、end

JVM的线程状态

JVM线程可描述为六种状态,在Thread中有个枚举类型,即Thread.state:

public enum State {NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;
}
  • NEW:即线程刚创建,但未start()启动时的状态
  • RUNNABLE:表示当前线程正在运行。此时有两种可能:
    • 就绪状态:
      • start():启动线程,进入就绪状态,等待调度程序调度
      • 当前线程sleep()结束,或是其他线程join()结束
      • yield()出让线程
    • 运行中状态:
      • 线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态(也是线程进入运行中状态的唯一方法)
  • BLOCKED:在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态,阻塞等待其他线程释放锁
  • WAITING:调用一些方法后会进入或设计等待状态,比如
    • Object.wait():使当前线程处于等待状态直到另一个线程通过notify()显式唤醒它;
    • Thread.join():插队,等待线程执行完毕,底层调用的是Object实例的wait方法;
    • LockSupport.park():除非获得调用许可,否则禁用当前线程进行线程调度。
    • 处于等待状态的
  • TIMED_WAITING:与WAITING类似,但是有指定的等待时间,比如:
    • Thread.sleep(long millis):使当前线程睡眠指定时间
    • Object.wait(long timeout):线程休眠指定时间,等待期间可以通过notify()/notifyAll()唤醒;
    • Thread.join(long millis):等待当前线程最多执行millis毫秒,如果millis为0,则会一直执行;
    • 上述三种方法使线程等待后,可以通过Interrupt()显示唤醒(中断等待)
  • TERMINATED:run()方法完成时或者主线程main()方法完成时,线程就会关闭终止
    • 在一个终止的线程上调用 start() 方法,会抛出 java.lang.IllegalThreadStateException 异常

另外,我们可以通过创建线程的getState()方法获取当前线程状态,或者感兴趣的朋友可以去了解下Jstack怎么做线程状态分析,可以用来排查死锁或者一些CPU占用过高的问题

JVM线程与OS线程的状态关系

Java线程的状态只会因为自身程序执行而发生转变,一般内核不会改变JVM线程状态

JVM线程与OS线程不一定是对应的,需要通过映射完成:

  • NEW 创建状态,对应OS线程的创建状态 new

  • TERMINATED 销毁状态,对应OS线程的销毁状态 end

  • RUNNABLE 运行状态,对应OS线程的run运行状态ready就绪状态:只要操作系统正在运行,JVM就判定线程为run,并不一定对应内核线程的run状态。

    • 有时,OS线程阻塞,单JVM看来OS仍在运行。比如Scanner.in与Scoket.accpet等待输入时,JVM线程还是run状态,而其映射的内核线程状态是wait
  • WAITING 等待状态,对应OS线程的wait状态:一般是由于调用了wait一类的方法陷入等待。

    • wait的作用-线程协作机制:

      线程间并不都是竞争关系,也有协作关系。比如,一般一个进程中的多个线程除了普通线程外,还包括消耗线程、增加线程。消耗线程与增加线程间就是协作关系(生产者与消费者),所以需要wait,然后用notify特定唤醒,如果不特定唤醒,则会陷入线程的忙等待(比如说消耗线程没数据消费了,但是生产线程一直竞争不到执行权,没法生产新数据,消耗线程就一直等着)

      注意一下,wait通过notify唤醒后并不会立即执行,而是跟其他线程一起重新竞争锁 资源
      请添加图片描述

  • TIMED_WAITING 定时等待,对应OS线程的:相当于有限时间的wait,通过sleep等方式转变,通过interrupt打断。

    • sleep时会有锁的释放吗?

      不会,sleep本身与并发关系不大,不会进行锁操作,此时如果有synchronized同步块,其他线程仍然不能访问共享数据。

  • BLOCKED 无法获取锁时的阻塞,就对应OS的block状态

    • WAITINGBLOCKED 的区别,一个是主动,一个是被动

Reference

https://www.runoob.com/java/thread-status.html
http://concurrent.redspider.group/article/01/4.html
https://www.bilibili.com/video/BV172421P7MB/?share_source=copy_web&vd_source=e40b707ba9b46ace5a15c44fb5fa3388
https://juejin.cn/post/7016228406220029983
https://www.zhihu.com/question/64100112/answer/218379442

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/792994.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CCIE-08-BGP-Listen

目录 实验条件网络拓朴实验目的 开始配置配置动态路由协议配置BGP检查邻居配置 实验条件 网络拓朴 实验目的 将R1配置成Listen状态,自动接收来自其它路由器的建邻居请求、建立邻居 开始配置 配置动态路由协议 这里用EIGRP来配置,保证网络的可达性&a…

替代 Redis 和 Memcached:25 倍吞吐量! | 开源日报 No.213

dragonflydb/dragonfly Stars: 22.4k License: NOASSERTION Dragonfly 是一个内存数据存储,适用于现代应用工作负载,可替代 Redis 和 Memcached。与传统的内存数据存储相比,Dragonfly 提供了 25 倍的吞吐量、更高的缓存命中率和更低尾部延…

基于springboot的粮仓管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…

java数组.day16(冒泡排序,稀疏数组)

冒泡排序 冒泡排序无疑是最为出名的排序算法之一,总共有八大排序! 冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知。 我们看到嵌套循环,应该立马就可以得出这个算法的时…

1.Spring Boot框架整合

Spring Boot项目创建&#xff08;约定大于配置&#xff09; 2.1.3.RELEASE版本示例 idea创建 从官网下载&#xff08;https://start.spring.io/&#xff09;单元测试默认依赖不对时&#xff0c;直接删除即可 Web支持&#xff08;SpringMVC&#xff09; <dependency>&…

Collection与数据结构 链表与LinkedList(三):链表精选OJ例题(下)

1. 分割链表 OJ链接 class Solution {public ListNode partition(ListNode head, int x) {if(head null){return null;//空链表的情况}ListNode cur head;ListNode formerhead null;ListNode formerend null;ListNode latterhead null;ListNode latterend null;//定义…

见证历史:Quantinuum与微软取得突破性进展,开启了可靠量子计算的新时代!

Quantinuum与微软的合作取得了重大突破&#xff0c;将可靠量子计算带入了新的时代。他们结合了Quantinuum的System Model H2量子计算机和微软创新的量子比特虚拟化系统&#xff0c;在逻辑量子比特领域取得了800倍于物理电路错误率的突破。这一创新不仅影响深远&#xff0c;加速…

目标检测——监控下的汽车

一、重要性及意义 首先&#xff0c;车辆检测技术是保证视频监控系统正常运行的基础。通过监控摄像头实时获取的图像&#xff0c;可以自动检测出图像中的车辆&#xff0c;并进行车辆类型的分类和识别。这对于优化城市交通管理、实现智能交通系统具有重要意义。此外&#xff0c;…

【SQL Server的详细使用教程】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【QT+QGIS跨平台编译】056:【pdal_lepcc+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

点击查看专栏目录 文章目录 一、pdal_lepcc介绍二、pdal下载三、文件分析四、pro文件五、编译实践一、pdal_lepcc介绍 pdal_lepcc 是 PDAL(Point Data Abstraction Library)的一个插件,用于点云数据的压缩。它基于 EPCC(Entwine Point Cloud Compression)算法,提供了对点…

51单片机入门之独立按键

目录 1.按键简介 2.独立按键控制LED亮灭 3.独立按键控制LED移位 1.按键简介 在生活中&#xff0c;我们常常会见到各种按键&#xff0c;我们的开发板上也有按键&#xff0c;就在左下角有四个按键&#xff0c;我们把它们叫做独立按键。 独立按键的原理比较简单&…

【机器学习】《机器学习算法竞赛实战》第7章用户画像

文章目录 第7章 用户画像7.1 什么是用户画像7.2 标签系统7.2.1 标签分类方式7.2.2 多渠道获取标签7.2.3 标签体系框架 7.3 用户画像数据特征7.3.1 常见的数据形式7.3.2 文本挖掘算法7.3.3 神奇的嵌入表示7.3.4 相似度计算方法 7.4 用户画像的应用7.4.1 用户分析7.4.2 精准营销7…

vscode-keil一起用

安装插件 1、C/C Extension Pack 2、Keil Assistant 配置 重启生效&#xff01;&#xff01;&#xff01; 下载安装 Mingw 下载链接&#xff1a; 添加环境变量&#xff1a; 注意确认&#xff01;&#xff01;&#xff01; 报错 gccC:\迅雷下载\MinGW\MinGW\bin…

力扣爆刷第111天之CodeTop100五连刷41-45

力扣爆刷第111天之CodeTop100五连刷41-45 文章目录 力扣爆刷第111天之CodeTop100五连刷41-45一、232. 用栈实现队列二、4. 寻找两个正序数组的中位数三、31. 下一个排列四、69. x 的平方根五、8. 字符串转换整数 (atoi) 一、232. 用栈实现队列 题目链接&#xff1a;https://le…

注解(Annotation)

10.1 注解概述 10.1.1 什么是注解 注解&#xff08;Annotation&#xff09;是从JDK5.0开始引入&#xff0c;以“注解名”在代码中存在。例如&#xff1a; Override Deprecated SuppressWarnings(value”unchecked”) Annotation 可以像修饰符一样被使用&#xff0c;可用于修饰…

ChatGPT 之赋能提示词工程

原文&#xff1a;Chatgpt Empowers Your Prompt Engineering with AI Tools 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 介绍 在当今这个时代&#xff0c;设计和人工智能工具对于企业在不断发展的市场中蓬勃发展至关重要。ChatGPT 为探索一系列可能性提供了机会&am…

中兴天机A31 A31PRO 5G zte A2122H te A2022H 解锁BootLoader root权限 教程magisk,原厂刷机包

zte A2122H P768A02 zte A2022H P875A02 中兴天机A31 A31PRO 5G zte A2122H te A2022H 解锁BootLoader root教程magisk&#xff0c;原厂刷机包 感谢 某大神支持&#xff0c;已经解锁root 刷了面具&#xff1b; 中兴天机A31 A31PRO 5G zte A2122H te A2022H 解锁BootLoad…

深入浅出 -- 系统架构之单体架构和微服务架构的区别

在软件开发中&#xff0c;架构设计是非常重要的一环。架构设计不仅决定了软件系统的性能、可维护性和扩展性&#xff0c;还直接关系到开发成本和项目进度。目前&#xff0c;主流的架构设计模式有两种&#xff0c;一种是单体架构&#xff0c;另一种是微服务架构。本文将详细介绍…

CVPR24_ArGue: Attribute-Guided Prompt Tuning for Vision-Language Models

Abstract 尽管软提示微调在调整视觉语言模型以适应下游任务方面表现出色&#xff0c;但在处理分布偏移方面存在局限性&#xff0c;通过属性引导提示微调&#xff08;Attribute-Guided&#xff0c;ArGue&#xff09;来解决这个问题 Contributions 与直接在类名之前添加软提示…

【Linux】Ubuntu 磁盘管理

准备一个U盘或者SD卡&#xff08;含读卡器&#xff09;&#xff0c;并将其格式化成 FAT32 格式&#xff0c;不要使用NTFS格式&#xff08;这是微软的专利&#xff0c;大部分Linux系统不支持&#xff09;和exFAT格式&#xff08;有的Linux系统也不支持&#xff09;。 如果Ubun…