06.深入学习Java 线程

1 线程的状态/生命周期

        Java 的 Thread 类对线程状态进行了枚举:

public class Thread implements Runnable {public enum State {NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;}
}
  1. 初始(NEW):新创建了一个线程对象,但还没有调用 start()方法。
  2. 运行(RUNNABLE):Java 线程中将就绪(ready)和运行中(running)两种  状态笼统的称为“运行”。
    1. 线程对象创建后,其他线程(比如 main 线程)调用了该对象的start()方法。  该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU 的使用权, 此时处于就绪状态(ready)。就绪状态的线程在获得 CPU 时间片后变为运行中状态(Running)。
  3. 阻塞(BLOCKED):表示线程阻塞于锁。
  4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作  (通知或中断)。
  5. 超时等待(TIMED_WAITING):该状态不同于 WAITING,它可以在指定的时间后自行返回。
  6. 终止(TERMINATED):表示该线程已经执行完毕。

        线程状态之间的变迁如下图所示:

2 线程的调度

        线程的状态的变迁是因为存在线程调度。

        线程调度是指系统为线程分配 CPU 使用权的过程,主要调度方式有两种:

  • 协同式线程调度(Cooperative Threads-Scheduling)。
  • 抢占式线程调度(Preemptive Threads-Scheduling)。

        使用协同式线程调度的多线程系统,线程执行的时间由线程本身来控制,线程把自己的工作执行完之后,要主动通知系统切换到另外一个线程上。使用协同式线程调度的最大好处是实现简单,由于线程要把自己的事情做完后才会通知系统进行线程切换,所以没有线程同步的问题,但是坏处也很明显,如果一个线程出了问题,则程序就会一直阻塞。

        使用抢占式线程调度的多线程系统,每个线程执行的时间以及是否切换都由系统决定。在这种情况下,线程的执行时间不可控,所以不会有「一个线程导致整个进程阻塞」的问题出现。

2.1 Java 线程调度就是抢占式调度

        为什么Java 线程调度是抢占式调度?这需要我们了解 Java 中线程的实现模式。

        我们已经知道线程其实是操作系统层面的实体,Java 中的线程怎么和操作系统层面对应起来呢?

        任何语言实现线程主要有三种方式:使用内核线程实现(1:1 实现),使用用户线程实现(1:N 实现),使用用户线程加轻量级进程混合实现(N:M 实现)。

2.1.1 内核线程实现

        使用内核线程实现的方式也被称为1:1 实现。内核线程(Kernel-Level  Thread, KLT) 就是直接由操作系统内核(Kernel, 下称内核)支持的线程。

        这种线程由内核来完成线程切换,内核通过操纵调度器(Scheduler) 对线程进行调度,并负责将线程的任务映射到各个处理器上。

        由于内核线程的支持,每个线程都成为一个独立的调度单元,即使其中某一个在系统调用中被阻塞了,也不会影响整个进程继续工作,相关的调度工作也不需要额外考虑,已经由操作系统处理了。

        局限性:首先,由于是基于内核线程实现的,所以各种线程操作,如创建、 析构及同步,都需要进行系统调用。而系统调用的代价相对较高,需要在用户态(User Mode)和内核态(Kernel Mode)中来回切换。其次,每个语言层面的线程都需要有一个内核线程的支持,因此要消耗一定的内核资源(如内核线程的栈空间),因此一个系统支持的线程数量是有限的。

2.1.2 用户线程实现

        严格意义上的用户线程指的是完全建立在用户空间的线程库上,系统内核不能感知到用户线程的存在及如何实现的。用户线程的建立、同步、销毁和调度完全在用户态中完成,不需要内核的帮助。如果程序实现得当,这种线程不需要切换到内核态,因此操作可以是非常快速且低消耗的,也能够支持规模更大的线程数量,部分高性能数据库中的多线程就是由用户线程实现的。

        用户线程的优势在于不需要系统内核支援,劣势也在于没有系统内核的支援,所有的线程操作都需要由用户程序自己去处理。线程的创建、销毁、切换和调度都是用户必须考虑的问题,而且由于操作系统只把处理器资源分配到进程,那诸如“阻塞如何处理”“多处理器系统中如何将线程映射到其他处理器上”这类问 题解决起来将会异常困难,甚至有些是不可能实现的。因为使用用户线程实现的程序通常都比较复杂,所以一般的应用程序都不倾向使用用户线程。Java 语言曾经使用过用户线程,最终又放弃了。但是近年来许多新的、以高并发为卖点的编程语言又普遍支持了用户线程,譬如Golang。

2.1.3 混合实现

        线程除了依赖内核线程实现和完全由用户程序自己实现之外,还有一种将内核线程与用户线程一起使用的实现方式,被称为 N:M 实现。在这种混合实 现下,既存在用户线程,也存在内核线程。

        用户线程还是完全建立在用户空间中,因此用户线程的创建、切换、析构等操作依然廉价,并且可以支持大规模的用户线程并发。

        同样又可以使用内核提供的线程调度功能及处理器映射,并且用户线程的系统调用要通过内核线程来完成。在这种混合模式中,用户线程与轻量级进程的数量比是不定的,是 N:M 的关系。

2.1.4 Java 线程的实现

        Java 线程在早期的Classic 虚拟机上(JDK 1.2 以前),是用户线程实现的, 但从JDK 1.3 起,主流商用 Java 虚拟机的线程模型普遍都被替换为基于操作系统原生线程模型来实现,即采用1:1 的线程模型。

        以 HotSpot 为例,它的每一个 Java 线程都是直接映射到一个操作系统原生线程来实现的,而且中间没有额外的间接结构,所以 HotSpot 自己是不会去干涉线程调度的,全权交给底下的操作系统去处理。

        所以,这就是我们说 Java 线程调度是抢占式调度的原因。而且Java 中的线程优先级是通过映射到操作系统的原生线程上实现的,所以线程的调度最终取决于操作系统,操作系统中线程的优先级有时并不能和 Java 中的一一对应,所以 Java 优先级并不是特别靠谱。

3 线程的优先级

        在Java 线程中,通过一个整型成员变量 priority 来控制优先级,优先级的范 围从1~10,在线程构建的时候可以通过 setPriority(int)方法来修改优先级,默认优先级是5,优先级高的线程分配时间片的数量要多于优先级低的线程。

        设置线程优先级时,针对频繁阻塞(休眠或者I/O 操作)的线程需要设置较高优先级,而偏重计算(需要较多CPU 时间或者偏运算)的线程则设置较低的优先级,确保处理器不会被独占。这只是相对应的理论,实际上,在不同的JVM 以及操作系统上,线程规划会存在差异,有些操作系统甚至会忽略对线程优先级的设定。通过上面对线程调度的分析我们就可以得出的结论。

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

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

相关文章

panic: concurrent write to websocket connection【golang、websocket】

文章目录 异常信息原由代码错误点 解决办法 异常信息 panic: concurrent write to websocket connection原由 golang 编写 websocket go版本:1.19 使用了第三方框架: https://github.com/gorilla/websocket/tree/main 代码 server.go // Copyright …

Linux - crond任务调度、at定时任务

1 crontab 进行-定时任务的设置 1)概述: 任务调度:是指系统在某个时间执行的特定的命令或程序。 任务调度分类: 系统工作:有些重要的工作必须周而复始地执行。如病毒扫描等个别用户工作:个别用户可能希…

Vue3实战笔记(38)—粒子特效终章

文章目录 前言一、怎样使用官方提供的特效二、海葵特效总结 前言 官方还有很多漂亮的特效,但是vue3只有一个demo,例如我前面实现的两个页面就耗费了一些时间,今天记录一下tsparticles官方内置的几个特效的使用方法,一般这几个就足…

SSM志愿服务管理小程序-计算机毕业设计源码97923

摘 要 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,志愿服务管理小程序被用户普遍使用,方便用户能…

Vue3:动态路由+子页面(新增、详情页)动态路由配置(代码全注释)

文章目录 实现思路调用后端接口获取用户权限获取页面权限动态绑定到路由对象中动态添加子页面路由 实现思路 emm,项目中使用动态路由实现根据后端返回的用户详情信息,动态将该用户能够访问的页面信息,动态生成并且绑定到路由对象中。但是后…

【C语言】实现贪吃蛇--项目实践(超详细)

前言: 贪吃蛇游戏大家都玩过吧?这次我们要用C语言来亲手制作一个!这个项目不仅能让我们复习C语言的知识,还能了解游戏是怎么一步步做出来的。我们会一起完成蛇的移动、食物的生成,还有碰撞检测等有趣的部分。准备好了…

客服快捷回复话术分享:618议价话术和催发货话术

随着618活动大促的临近,客服小伙伴们将迎来一年中最繁忙的时刻。面对顾客的议价、催发货等需求,我们应该如何回复才能既满足顾客的需求,又能保持良好的服务形象呢?下面就为大家分享一些议价和催发货的快捷回复话术,希望…

55页PDF|人工智能通用大模型(ChatGPT)的进展、风险与应对(附下载)

👉获取方式: 😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

WIFI国家码设置的影响

记录下工作中关于国家码设置对WIFI的影响,以SKYLAB的SKW99和SDZ202模组为例进行说明。对应到日常,就是我们经常提及手机是“美版”“港版”等,它们的wifi国家码是不同的,各版本在wifi使用中遇到的各种情况与下面所述是吻合的。 现…

从alpine构建预装vcpkg的docker image用于gitea actions CI

动机 想要构建一个基于vcpkg的交叉编译容器平台用于cpp项目的CI(自动集成),此处仅提供最基础的image,amd64的机子上构建完成后大小为533兆(着实不小😓),各位看官可以在此基础上自行构建需要的版本。 hello world效果展示 corss_compiler.dockerfile FROM alpine:la…

【Ubuntu常用命令】终端个人常用命令总结

【Ubuntu常用命令】终端常用命令总结 查看硬盘挂载情况查看内存占用情况移动或重命名文件和目录复制文件或目录 查看硬盘挂载情况 mount 命令会列出当前系统上所有已挂载的文件系统。它会显示挂载点、文件系统类型、挂载选项等信息 mount df 命令用于显示文件系统的磁盘空间使…

springboot 集成 es--未完结

基于es7.10.x版本 一、前提知识 常见的两种方式:spring boot提供的API 和 ES 官方提供的API ES官方: RestHighLevelClient: 适用于复杂、更细粒度控制的Elasticsearch 操作 spring boot: ElasticsearchRestTemplate&#xff1a…

linux查看是否被入侵(一)

1、查看当前系统状态 [rootbastion-IDC ~]#top #一般挖矿等病毒点用CPU比较大 2、查看当前登录用户(w\who) 3、检查系统日志 检查系统错误登陆日志,统计IP重试次数 [rootbastion-IDC ~]# lastb 4、查看近期用户登录情况 [rootkvm01 ~]# last -n 5 #-n 5 表示…

软件3班20240527

JDK 版本与 Tomcat 的 兼容性

nginx流量监控:goAccess安装与使用

关于goAccess GoAccess 是一款实时、快速的日志分析工具,专门设计用于分析Web服务器日志,特别是Nginx日志。 安装 (1)准备相关依赖 # Missing development libraries for ncursesw # centOS yum install -y ncurses-devel # U…

【EI会议】2024年互联网技术与环境工程国际会议(IACITEE 2024)

【EI会议】2024年互联网技术与环境工程国际会议(IACITEE 2024) 2024 International Conference on Internet Technology and Environmental Engineering 互联网技术与环境工程国际会议(IACITEE 2024)将在重庆举行,主…

怎么把记事本钉在桌面上 桌面记事本固定不动的方法

我的生活,总是被密密麻麻的待办事项和灵感想法填得满满当当。记事本,就是我随身的记忆银行,帮我存储那些稍纵即逝的思维火花和不能错过的琐事提醒。每当翻开那一页页工整的笔记,心中的焦虑和压力似乎都找到了释放的出口。 但一直…

锐捷网络与您相约第七届数字中国建设峰会 共话数字未来

第七届数字中国建设峰会将于5月24日至25日在福建福州举办,本届峰会是国家数据工作体系优化调整后首次举办的数字中国建设峰会,主题是“释放数据要素价值,发展新质生产力”。作为行业领先的ICT基础设施及解决方案提供商,锐捷网络与福建省电子信息集团、星网锐捷,围绕“发展新质生…

mvc的常见注解

问文心一言的,记录一下。 PathVariable 路径变量注解 PathVariable 是 Spring MVC 提供的一个注解,它用于从 URI 模板变量中绑定值到控制器方法的参数上。当你在 RequestMapping、GetMapping、PostMapping、PutMapping、DeleteMapping 等注解的 URL 路…

基于深度学习和opencv的车牌识别系统

免费获取方式↓↓↓ 项目介绍028: 基于深度学习和opencv的车牌识别系统 同时利用对图片每一帧图像加入视频分析模块 图片分析模块可以依据界面按钮提示进行相应功能 视频分析模块可以根据按钮提示进行对视频的分析 (视频模块的视频追踪处理时间较长&…