Java虚拟机——线程与协程

news2024/12/25 9:15:15

1 Java与线程

  • 目前线程是Java里面进行处理器资源调度的最基本单位。如果日后Loom项目能够为Java引入纤程(Fiber)的话,可能会改变这一点。

1.1 线程的实现

  • 这里先把Java技术的背景放下,以一个通用的应用程序的角度来看线程是如何实现的。

1.1.1 内核线程实现

  • 利用内核线程实现的方式也被称为1:1实现。内核线程是直接由操作系统支持的线程,这种线程由内核来完成线程切换,内核通过操纵调度器对线程进行调度,并负责将线程的任务映射到各个处理器上。
  • 每个内核线程都可以视为一个内核的分身,这样子操作系统就有能力同时处理多件事情,支持多线程的内核就称为多线程内核
  • 一般不会直接使用内核线程,而是使用内核线程的一种高级接口——轻量级进程,轻量级进程就是我们通常意义上讲的线程,每个轻量级进程都由一个内核线程支持。但是使用内核线程,所有的线程操作都需要交给系统调用,而系统调用的代价是相对较高的,需要在用户态和内核态中来回切换。

1.1.2 用户线程实现

  • 用户线程实现的方式被称为1:N实现,广义上来讲,一个线程只要不是内核线程,都可以认为是用户线程。从定义上说,轻量级进程也属于用户线程,但是因为它的实现始终是建立在内核上的,通常意义上并不具备用户线程的优点。
  • 狭义的用户线程是建立在用户空间的线程库上的,系统不能感知到用户线程的存在。用户线程的建立、同步、销毁和调度完全在用户态中完成。 如果程序实现得当,这种线程不需要切换到内核态,因此操作非常快速且低耗的。
  • 但是困难在于用户需要自己处理所有的线程操作,有些问题会非常难以处理,Java语言曾经也使用过,但是还是放弃了。

1.1.3 混合实现

  • 将内核线程和用户线程结合起来使用的方式,被称为N:M实现
  • 用户线程还是完全建立在用户空间中,因此用户线程的创建、切换、析构等操作依然廉价,并且可以支持大规模的用户线程并发。
  • 操作系统支持的轻量级进程作为用户线程和内核线程之间的桥梁,这样可以使用内核提供的线程调度功能和处理器映射。大大降低了整个进程被完全堵塞的风险。
    在这里插入图片描述

1.2 Java线程调度

  • 线程调度是指系统为线程 分配处理器使用权的 过程。
  • 调度方式主要有两种:协同式线程调度和抢占式线程调度

1.2.1 协同式调度的多线程系统

  • 线程的执行时间由线程本身来控制,线程把自己的工作做完之后,要主动通知系统切换到另一个线程上去。
  • 好处:实现简单。切换操作对线程可知,一般没有线程同步问题。
  • 坏处:执行时间不可控,如果一个线程的代码编写有问题,那么不会告知系统进行线程切换,就会一直阻塞在那里。

1.2.2 抢占式调度的多线程系统

  • 每个线程将由系统来分配执行时间,线程的切换不由线程本身来决定。
  • Java中,通过Thread::yield()方法可以主动让出执行时间,但是如果想要主动获取执行时间,线程是没有什么办法的。
  • 线程的执行时间是系统可控的,所以不会有因为一个进程出问题,因为一个线程导致整个进程出了问题。

1.2.3 Java优先级

  • Java的线程调度是系统自动完成的,但是我们可以建议操作系统给某些线程多分配一些时间。这项操作可以通过设置线程优先级来完成。优先级越高的线程越容易被系统选择执行。
    在这里插入图片描述

状态转换

  • Java语言自定义了6种线程状态,在任意一个时间点中,一个线程只能有且只有其中的一种状态,并且可以通过特定的方法在不同状态之间转换。
  1. 新建(New):创建后尚未启动的线程处于这种状态
  2. 运行(Runnable):包括操作系统中的Running和Ready,也就是处于此状态的线程有可能在执行,也有可能在等待着操作系统为它分配时间。
  3. 无限期等待(Waiting):处于这种状态的线程不会被分配 处理器执行时间,它们要等待被其他线程显示唤醒。
  • 没有设置Timeout参数的Object::wait()方法
  • 没有设置Timeout参数的Thread::join()方法
  • LockSupport::park()
  1. 限期等待(Timed Waiting):处于这种状态的线程也不会被分配 处理器执行时间,不过无须等待被其他线程显示唤醒,在一定时间之后,系统会自动唤醒。
  • Thread::sleep()方法
  • 设置Timeout参数的Object::wait()方法
  • 设置Timeout参数的Thread::join()方法
  • LockSupport::parkNanos()方法
  • LockSupport::pakUntil()方法
  1. 阻塞(Blocked):线程被阻塞了的,"阻塞状态"与"等待状态"的区别是阻塞状态在等待着获取一个排它锁,这个事件将在另外一个线程放弃这个锁的时候发生。 而等待状态是等待一段时间,或者唤醒动作的发生。
  2. 结束(Terminated):已经终止线程的线程状态,线程已经结束执行。

2 Java与协程

  • 如今的请求越来越多,请求本身的执行时间变得很短,数量变得很多。
  • 但是因为Java目前的多线程机制就是采用内核线程模型,所以说线程之间的切换就会非常的频繁,这会造成严重的浪费。内核线程调度的成本主要来自于用户态与核心态之间的状态转换,而这两者之间的开销来自于响应中断、保护和恢复执行现场的成本。
  • 当中断发生时,线程A切换到线程B之前,操作系统首先要把线程A的上下文数据妥善保管好,然后把寄存器、内存分页等恢复到线程b挂起时候的状态,这样线程B被重新激活后才能仿佛从来没有挂起。 这种保护和恢复现场的工作,免不了涉及一系列数据在各种寄存器、缓存中来回的拷贝,当然不可能是一种轻量级的操作。

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

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

相关文章

C数据结构与算法——顺序查找和二分查找算法 应用

实验任务 (1) 掌握顺序查找算法的实现; (2) 掌握二分查找算法的实现; (3) 掌握两种查找算法的时间复杂度与适用场合。 实验内容 (1) 基于顺序查找表实现顺序查找和二分查找算法; (2) 使用两个不同大小的查找表进行两次理论和实际性能对比&…

利用STM32为主控以LORA为通讯模块,通过中继器链接MQTT服务器的物联网信息采集处理的信息系统方案

项目的详细方案如下: 硬件组成: STM32主控板:作为项目的主控单元,负责采集终端点位的温湿度信息,并通过LORA通讯模块发送数据到中继器。 LORA通讯模块:作为STM32与中继器之间的无线通信模块,负…

【NLP】语音识别 — GMM, HMM

一、说明 在语音识别的深度学习(DL)时代之前,HMM和GMM是语音识别的两项必学技术。现在,有将HMM与深度学习相结合的混合系统,并且有些系统是免费的HMM。我们现在有更多的设计选择。然而,对于许多生成模型来说…

浅谈集成式电力电容器无功补偿装置的技术特点及应用状况

安科瑞 华楠 摘要:阐述了集成式电力电容器无功补偿装置的组成与应用状况.在与常规电力电容器对比的基础上,分析了集成式电力电容器无功补偿装置的技术特点。通过对集成式无功补偿装置原理结构的分析,探讨了对集成式无功补偿装置的…

Spring Batch教程(四)tasklet使用示例:spring batch的定时任务使用

Spring batch 系列文章 Spring Batch教程(一) 简单的介绍以及通过springbatch将xml文件转成txt文件 Spring Batch教程(二)示例:将txt文件转成xml文件以及读取xml文件内容存储到数据库mysql Spring Batch教程&#xff…

TPU-MLIR编译部署算法

注意: 由于SOPHGO SE5微服务器的CPU是基于ARM架构,以下步骤将在基于x86架构CPU的开发环境中完成 初始化开发环境(基于x86架构CPU的开发环境中完成)模型转换 (基于x86架构CPU的开发环境中完成) 处理后的PP-OCR项目文件将被拷贝至 SE5微服务器 上进行推理…

el-table-column 合并列,切换表格显示,数据错乱问题

由于同一个页面需要通过lable进行切换显示不同的表格结果在切换的时候发现表格列错乱了 正常是这样的 切换错乱的是这样的 序号没有了,已接单协同总数列也不见了 切换回来发现第一个表格 原先的两列被后面的挤压了 代码也没啥毛病,最主要的原因是因为同…

【从零开始学习JAVA | 第三十二篇】 异常(下)新手必学!

目录 前言: Exceptions(异常): 异常的两大作用: 异常的处理方式: 1.JVM默认处理 2.自己捕获异常 3.抛出处理 自定义异常: 异常的优点: 总结: 前言: 前…

LUMEN技术要点总结

LUMEN总结 主题是动态全局光照和Lumen Lumen更像是一个各种GI算法的集大成者。 1. 如何理解lumen及全局光照的实现机制 渲染方程 至今为止所有的实时光照都是按照Render Equation来进行渲染的,我们做得到只是在无限的逼近它。 我们把只进行一次反弹叫做SingleBou…

uni-app 经验分享,从入门到离职(一)——初始 uni-app,快速上手(文末送书福利1.0)

文章目录 📋前言🎯什么是 uni-app🎯创建第一个 uni-app 项目🧩前期工作🧩创建项目(熟悉默认项目、结构)🧩运行项目 📝最后🎯文末送书🔥参与方式 &…

客户方数据库服务器CPU负载高优化案例

客户方数据库服务器CPU负载高优化案例 背景 上周线上服务出现一个问题,打开某个页面,会导致其它接口请求响应超时,排查后发现数据库响应超400s,之前1s就可查到数据。 具体原因是有个大屏统计页面,会实时查看各业务服…

echarts坐标轴名称换行

一、期望效果: 期望超过6个字换行,最多可显示十个字 如图: 二、踩坑: echarts的width和overflow设置后换行无效。(如果其他人有设置有效的 还请说明下) 三、解决方案: 用\n换行&#xf…

Django + Xadmin 数据列表复选框显示为空,怎么修复这个问题?

问题描述: 解决方法: 后续发现的报错: 解决方案: 先根据报错信息定位到源代码: 在该文件顶部写入: from django.core import exceptions然后把: except models.FieldDoesNotExist修改为&…

qt6.5 download for kali/ubuntu ,windows (以及配置选项选择)

download and sign in qt官网 sign in onlion Install 1 2 3 4 5

SpringBoot整合WebService

SpringBoot整合WebService WebService是一个比较旧的远程调用通信框架,现在企业项目中用的比较少,因为它逐步被SpringCloud所取代,它的优势就是能够跨语言平台通信,所以还有点价值,下面来看看如何在SpringBoot项目中使…

Neo4j图数据基本操作

Neo4j 文章目录 Neo4jCQL结点和关系增删改查匹配语句 根据标签匹配节点根据标签和属性匹配节点删除导入数据目前的问题菜谱解决的问题 命令行窗口 neo4j.bat console 导入rdf格式的文件 :GET /rdf/ping CALL n10s.graphconfig.init(); //初始化 call n10s.rdf.import.fetch(&q…

每日一题——两个链表的第一个公共结点

题目 输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的) 数据范围: n≤…

LeetCode 75 第十一题(392)判断子序列

题目: 示例: 分析: 给两个字符串s和t,问s是不是t的子序列.即判断t中能不能提取出s(s有的元素,t都要有.并且字符的相对顺序不能变,如果字符的相对顺序能变的话就不能用双指针来做,而是要用哈希表了,可以参考力扣383赎金信这题). 这题虽然简单,但是是练习双指针的一个很好的题目…

【QT】Day3

1. 完成闹钟的实现&#xff1a; widgt.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QDebug> #include <QTimerEvent> //定时器事件处理函数 #include <QTime> //时间类 #include <QTextToSpeech> //文本转语音类头…

ARP协议(地址解析协议)详解

ARP协议&#xff08;地址解析协议&#xff09;详解 ARP协议的作用映射方式静态映射动态映射 ARP原理及流程ARP请求ARP响应 ARP协议报文首部 ARP协议的作用 ARP协议是“Address Resolution Protocol”&#xff08;地址解析协议&#xff09;的缩写。其作用是在以太网环境中&…