java的线程是用户态还是内核态_内核态和用户态的区别

java的线程是用户态还是内核态_内核态和用户态的区别内核态用户态是什么?操作系统对程序的执行权限进行分级,分别为用户态和内核态。用户态相比内核态有较低的执行权限,很多操作是不被操作系统允许的,简单来说就是用户态只能访问内存,防止程序错误影响到其他程序,而内核态则是可以操作系统的程序和普通用户程序内核态:cpu可以访问计算机所有的软硬件资源用户态:cpu权限受限,只能访问到自己内存中的数据,无法访问其他资源为什么要有用户态和内核态?系统需要限制不同的程序之间的访问能力,防止程序获取不相同程序的内存数据,或者外围设备的数据,并发送到网络,所有cpu

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

内核态用户态是什么?

操作系统对程序的执行权限进行分级,分别为用户态和内核态。用户态相比内核态有较低的执行权限,很多操作是不被操作系统允许的,简单来说就是用户态只能访问内存,防止程序错误影响到其他程序,而内核态则是可以操作系统的程序和普通用户程序

内核态: cpu可以访问计算机所有的软硬件资源

用户态: cpu权限受限,只能访问到自己内存中的数据,无法访问其他资源

为什么要有用户态和内核态?
系统需要限制不同的程序之间的访问能力,防止程序获取不相同程序的内存数据,或者外围设备的数据,并发送到网络,所有cpu划分出两个权限等级用户态和内核态

用户态和内核态的转换

在这里插入图片描述
用户应用程序在用户态下,但是如果需要执行一些操作例如申请内存,网络读写时,自己的权限不够,就需要转换到内核态去让内核去帮忙干一些事情,下面三个方式会进行转换

  1. 系统调用
    这是用户态主动要求切换到内核态的一种方式,用户进程通过系统调用申请使用操作系统提供的服务程序完成工作,比如前列中fork()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操作系统为用户特别开发的一个中断来实现,列表liunx的int 80h中断

  2. 异常
    当cpu在运行在用户态下的程序时,发生了些某些事先不可知的异常,这时会触发由当前运行进程切换此异常的内核相关程序中,也就转到了内核态

  3. 外围设备的中断
    当外围设备完成用户请求的操作后,会向CPU发出相应的中断信息,这时CPU会暂停执行下一条即将执行的指令而去执行与中断信号对应的处理程序,如果先前执行的指令时用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换,比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等

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

Java线程在jdk1.2之前,是基于称为”绿色线程”的用户线程实现,但从JDK1.3起,主流平台上的”主流”商用Java虚拟机的线程模型普遍都被替换为基于操作系统原生原生线程模型来实现,即采用1:1的线程模型

操作系统支持怎么样的线程模型,在很大程度想回影响上面的Java虚拟机的线程是怎么映射的,这一点在不同的平台上很难达成一致,因此《Java虚拟机规范》中才不去限定Java线程需要使用哪种线程模型来实现。

  1. 证明java线程不是纯粹用户级线程:java中有个fork join框架,这个框架是利用多处理技术进行maprudce的工作,也就证明了内核是可以感知到用户线程的存在,因此才会将多个线程调度到多个处理器中。还有,java应用程序中的某个线程阻塞,是不会引起整个进程的阻塞,从这两点看,java线程绝不是纯粹的用户级线程

  2. 再来证明java线程不是纯粹内核级线程:如果使用纯粹的内核级线程,那么有关线程的所有管理工作都是内核完成的,用户程序中没有管理线程的代码。显然,java线程库提供了大量的线程管理机制,因此java线程绝不是纯粹的内核级线程。 综上,java线程是混合型的线程模型,一般而言是通过lwp将用户级线程映射到内核线程中

Java线程用户态内核态切换

cpu采用时间轮片机制给每个线程分发执行时间片来让线程执行,如果线程在进行上下文切换,堵塞,时间片用完,睡眠,\等情况,就会发生用户态和内核态的切换

线程切换的调度器存放于内核中,中断处理也在内核。,从这个角度来说,如果线程当前处于用户态,若要发生线程切换,必然是要先进入内核态,发生状态切换的。线程切换的原因还可能是其他类型的中断,或者线程自身主动进入等待和睡眠.这些情况无一例外会进入内核。

但是线程当前就处于内核态,也可能一样中断,或者主动进入等待或者睡眠,这也是一样会发送的,但就是没有了用户态和内核态的状态切换了

总而言之线程切换和状态切换没有直接的关联,,只不过线程切换一般都放到内核实现而已,当然也还有所谓的用户级线程,也就是在用户态直接切换线程的栈和寄存器而已,这也无需切换到内核态

用户态和内核态切换性能问题

当发生用户态到内核态的切换时,会发生如下过程:

  1. 设置处理器至内核态。
  2. 保存当前寄存器(栈指针、程序计数器、通用寄存器)。
  3. 将栈指针设置指向内核栈地址。
  4. 将程序计数器设置为一个事先约定的地址上,该地址上存放的是系统调用处理程序的起始地址。
  5. 而之后从内核态返回用户态时,又会进行类似的工作。

用户态和内核态之间的切换有一定的开销,如果频繁发生切换势必会带来很大的开销,所以要想尽一切办法来减少切换

避免频繁切换

因为线程的切换会导致用户态和内核态之间的切换,所以减少线程切换也会减少用户态和内核态之间的切换。那么如何减少线程切换呢?

  • 无锁并发编程。多线程竞争锁时,加锁、释放锁会导致比较多的上下文切换
  • CAS算法。使用CAS避免加锁,避免阻塞线程
  • 使用最少的线程。避免创建不需要的线程协程。在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换

有兴趣的小伙伴可以加微信技术群,遇到问题可以一起讨论
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/194060.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • js数组对象转字符串方法_数组表示

    js数组对象转字符串方法_数组表示Js数组转对象(特殊格式)arr:[{},{},{}]转化为obj:{ {},{},{}}利用ES6语法:letobj={…arr};

    2022年9月10日
    0
  • 安卓微信本地数据库解密[通俗易懂]

    安卓微信本地数据库解密[通俗易懂]安卓微信数据库解密

    2022年5月6日
    230
  • java冒泡排序代码_Java冒泡排序

    java冒泡排序代码_Java冒泡排序一、冒泡排序:利用冒泡排序对数组进行排序二、基本概念:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2…

    2022年7月8日
    12
  • Android UI设计

    Android UI设计UI概述1、在Android应用中,UI(UserInterface)界面是人与手机之间数据传递、交互信息的重要媒介和对话接中。2、Android程序开发最重要的一个环节就是界面处理,界面的美观度直接影响用户的第一印象,因此,开发一个整齐、美观的界面是至关重要的。3、Android应用的界面是由View和ViewGroup对象构建而成的。View类是Android系统平台上用户界面表示的基本单元,View的一些子类被统称为Widgets(工具),它们提供了诸如文本输入框和按钮之类的UI对象

    2022年6月29日
    24
  • Executors和ThreadPoolExecutor学习整理

    任务的执行与线程池(上) https://mp.weixin.qq.com/s/p3JZERyZXnF8jR_3KKIGJA 任务的执行与线程池(下) https://mp.weixin.qq.com/s/iUAaVXIB8rCzP_GeDhIlqAjava并发编程–Executor 框架 https://www.cnblogs.com/MOBIN/p/5436482.html线程…

    2022年2月27日
    32
  • hbase列表排序

    hbase列表排序

    2021年12月17日
    177

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号