面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!

图片

  • 时间片

  • 超线程

  • 上下文切换

  • 切换查看

  • 线程调度

  • 引起线程上下文切换的因素


由于现在大多计算机都是多核CPU,多线程往往会比单线程更快,更能够提高并发,但提高并发并不意味着启动更多的线程来执行。更多的线程意味着线程创建销毁开销加大、上下文非常频繁,你的程序反而不能支持更高的TPS。

时间片

多任务系统往往需要同时执行多道作业。作业数往往大于机器的CPU数,然而一颗CPU同时只能执行一项任务,如何让用户感觉这些任务正在同时进行呢? 操作系统的设计者 巧妙地利用了时间片轮转的方式

时间片是CPU分配给各个任务(线程)的时间!

思考:单核CPU为何也支持多线程呢?

线程上下文是指某一时间点 CPU 寄存器和程序计数器的内容,CPU通过时间片分配算法来循环执行任务(线程),因为时间片非常短,所以CPU通过不停地切换线程执行。

换言之,单CPU这么频繁,多核CPU一定程度上可以减少上下文切换。

超线程

现代CPU除了处理器核心之外还包括寄存器、L1L2缓存这些存储设备、浮点运算单元、整数运算单元等一些辅助运算设备以及内部总线等。一个多核的CPU也就是一个CPU上有多个处理器核心,就意味着程序的不同线程需要经常在CPU之间的外部总线上通信,同时还要处理不同CPU之间不同缓存导致数据不一致的问题。

超线程这个概念是Intel提出的,简单来说是在一个CPU上真正的并发两个线程,由于CPU都是分时的(如果两个线程A和B,A正在使用处理器核心,B正在使用缓存或者其他设备,那AB两个线程就可以并发执行,但是如果AB都在访问同一个设备,那就只能等前一个线程执行完后一个线程才能执行)。实现这种并发的原理是 在CPU里加了一个协调辅助核心,根据Intel提供的数据,这样一个设备会使得设备面积增大5%,但是性能提高15%~30%。

上下文切换

  • 线程切换,同一进程中的两个线程之间的切换

  • 进程切换,两个进程之间的切换

  • 模式切换,在给定线程中,用户模式和内核模式的切换

  • 地址空间切换,将虚拟内存切换到物理内存

CPU切换前把当前任务的状态保存下来,以便下次切换回这个任务时可以再次加载这个任务的状态,然后加载下一任务的状态并执行。任务的状态保存及再加载, 这段过程就叫做上下文切换。

每个线程都有一个程序计数器(记录要执行的下一条指令),一组寄存器(保存当前线程的工作变量),堆栈(记录执行历史,其中每一帧保存了一个已经调用但未返回的过程)。

寄存器 是 CPU 内部的数量较少但是速度很快的内存(与之对应的是 CPU 外部相对较慢的 RAM 主内存)。寄存器通过对常用值(通常是运算的中间值)的快速访问来提高计算机程序运行的速度。

程序计数器是一个专用的寄存器,用于表明指令序列中 CPU 正在执行的位置,存的值为正在执行的指令的位置或者下一个将要被执行的指令的位置。

  • 挂起当前任务(线程/进程),将这个任务在 CPU 中的状态(上下文)存储于内存中的某处

  • 恢复一个任务(线程/进程),在内存中检索下一个任务的上下文并将其在 CPU 的寄存器中恢复

  • 跳转到程序计数器所指向的位置(即跳转到任务被中断时的代码行),以恢复该进程在程序中]

图片

图片

线程上下文切换会有什么问题呢?

上下文切换会导致额外的开销,常常表现为高并发执行时速度会慢串行,因此减少上下文切换次数便可以提高多线程程序的运行效率。

  • 直接消耗:指的是CPU寄存器需要保存和加载, 系统调度器的代码需要执行, TLB实例需要重新加载, CPU 的pipeline需要刷掉

  • 间接消耗:指的是多核的cache之间得共享数据, 间接消耗对于程序的影响要看线程工作区操作数据的大小

切换查看

Linux系统下可以使用vmstat命令来查看上下文切换的次数, 其中cs列就是指上下文切换的数目(一般情况下, 空闲系统的上下文切换每秒大概在1500以下)

图片

图片

线程调度

抢占式调度

指的是每条线程执行的时间、线程的切换都由系统控制,系统控制指的是在系统某种运行机制下,可能每条线程都分同样的执行时间片,也可能是某些线程执行的时间片较长,甚至某些线程得不到执行的时间片。在这种机制下,一个线程的堵塞不会导致整个进程堵塞。

java使用的线程调使用抢占式调度,Java中线程会按优先级分配CPU时间片运行,且优先级越高越优先执行,但优先级高并不代表能独自占用执行时间片,可能是优先级高得到越多的执行时间片,反之,优先级低的分到的执行时间少但不会分配不到执行时间。

图片

图片

协同式调度

指某一线程执行完后主动通知系统切换到另一线程上执行,这种模式就像接力赛一样,一个人跑完自己的路程就把接力棒交接给下一个人,下个人继续往下跑。线程的执行时间由线程本身控制,线程切换可以预知,不存在多线程同步问题,但它有一个致命弱点:如果一个线程编写有问题,运行到一半就一直堵塞,那么可能导致整个系统崩溃。

图片

图片

线程让出cpu的情况
  • 当前运行线程主动放弃CPU,JVM暂时放弃CPU操作(基于时间片轮转调度的JVM操作系统不会让线程永久放弃CPU,或者说放弃本次时间片的执行权),例如调用yield()方法。

  • 当前运行线程因为某些原因进入阻塞状态,例如阻塞在I/O上

  • 当前运行线程结束,即运行完run()方法里面的任务

引起线程上下文切换的因素

  • 当前执行任务(线程)的时间片用完之后,系统CPU正常调度下一个任务

  • 中断处理,在中断处理中,其他程序”打断”了当前正在运行的程序。当CPU接收到中断请求时,会在正在运行的程序和发起中断请求的程序之间进行一次上下文切换。中断分为硬件中断和软件中断,软件中断包括因为IO阻塞、未抢到资源或者用户代码等原因,线程被挂起。

  • 用户态切换,对于一些操作系统,当进行用户态切换时也会进行一次上下文切换,虽然这不是必须的。

  • 多个任务抢占锁资源,在多任务处理中,CPU会在不同程序之间来回切换,每个程序都有相应的处理时间片,CPU在两个时间片的间隔中进行上下文切换

因此优化手段有:
  • 无锁并发编程,多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash取模分段,不同的线程处理不同段的数据

  • CAS算法,Java的Atomic包使用CAS算法来更新数据,而不需要加锁

  • 使用最少线程

  • 协程,单线程里实现多任务的调度,并在单线程里维持多个任务间的切换

合理设置线程数目既可以最大化利用CPU,又可以减少线程切换的开销。

  • 高并发,低耗时的情况,建议少线程。

  • 低并发,高耗时的情况:建议多线程。

  • 高并发高耗时,要分析任务类型、增加排队、加大线程数

最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

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

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

相关文章

【好书推荐-第十五期】《 机器学习基础:从入门到求职》(博文视点出品)

😎 作者介绍:我是程序员洲洲,一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公众号:洲与AI。 🎈 本文专栏:本文收录…

IT精英的财富攻略:五大策略揭秘

IT精英的财富攻略:五大策略揭秘 💸 数字化浪潮汹涌,IT技能成为职场的金钥匙🔑,更为智慧的IT人打开了赚钱的大门。如果你身怀网络维护与安全管理的绝技,那么这五大策略,正是你蓄势待发的赚钱法宝…

c++的学习之路:19、模板

摘要 本章主要是说了一些模板,如非类型模板参数、类模板的特化等等,文章末附上测试代码与导图 目录 摘要 一、非类型模板参数 二、类模板的特化 1、概念 2、函数模板特化 3、类模板特化 三、模板的分离编译 1、什么是分离编译 2、模板的分离编…

针对MaxCompute优化案例分享

声明 原文来源:微信公众号:阿里云开发者 前言 MaxCompute 是阿里巴巴集团推出的一种大数据计算平台,用于处理海量数据和进行数据分析。它提供了高可靠性、高扩展性和高性能的数据处理能力,支持 SQL 查询、MapReduce 计算和机器…

利用vite创建vue项目

创建vue项目步骤 打开HBuilder X工具,创建空白项目 进入终端(鼠标点击文件进行选择,然后终端) 利用vite脚手架创建项目 (前提要将HBuilder X工具属性设为管理员运行状态(属性》兼容》管理员身份运行此程序) npm …

【C++】3.类和对象(中)

一、类的6个默认成员函数 在上一篇博客中,我们计算了空类的大小为 1 。那么空类中真的什么东西都没有吗?其实不是的,当一个类在什么都不写的时候就会自动生成6个默认的成员函数(用户没有写,但是编译器自动生成的成员函…

leetcode代码记录(寻找两个正序数组的中位数

目录 1. 题目:2. 我的代码:小结: 1. 题目: 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1…

浅谈locust 性能压测使用

1. 基本介绍 Locust是一个开源的负载测试工具,用于模拟大量用户并发访问一个系统或服务,以评估其性能和稳定性。编写语言为Python,可通过Python来自定义构建性能压测场景脚本。Locust支持分 布式负载测试,可以通过多个机器协同工…

动态消息系统设计

动态消息流是一个在你个人主页不同更定的故事列表,推特、mega和Instagram 的post消息都是典型的动态消息列表,和普通消息流系统的最大区别是消息流动态变化、实时更新,设计一个动态消息系统核心功能消息流的构建和消息的发布,需要…

算法学习系列(四十八):数字三角形模型

目录 引言闫氏DP分析法一、摘花生二、最低通行费三、方格取数四、传纸条 引言 今天开始学习进阶版的 D P DP DP 问题,还是按照知识点来分,按照题目来进行讲解,这个 D P DP DP 问题尤其是算法竞赛是非常容易考的,因为感觉大部分…

SQL注入sqli_labs靶场第十七题

B站教学视频很详细 【sql注入之sqli-labs系列教程(less11-17)】sqli-labs_33_less17_哔哩哔哩_bilibili 我将SQL语句在页面中显示,以便更深入学习。 1.寻找注入点 修改密码的一个页面。 输入正确的账号密码,可以看到,账号为admin&#xf…

华为数通方向HCIP-DataCom H12-821题库(多选题:321-340)

第321题 关于OSPF的命令描述,不正确的是: A、stub区域和totally stub区域配置了no-summary参数 B、OSPFv2和OSPF v3配置接口命令的区别是OSPF V2可以使用network命令,而OSPFv3直接 C、在接口上使能stubrouter命令用来配置次路由器为stub路由器,stub路由器可以与非stub路由 …

​元宇宙之聲|突破文化界限 艾肯娛樂如何通過元宇宙傳揚台湾文化

​台湾游戏公司艾肯娛樂通过其子公司艾琺數位,在2022年7月踏上了一段充满激情的 Web3 之旅。 旨在融合创意、文化和尖端技术,他们深入探索区块链,专注于创建独特的 NFT 和元宇宙体验。通过结合营销和创新,他们通过 Web3 的视角向世…

提升Jmeter测试效率的9种参数化方法!

jmeter工具无论做接口测试还是性能测试,参数化都是一个必须掌握且非常有用的知识点。参数化的使用场景: 1)多个请求都是同一个ip地址,若服务器地址更换了,则脚本需要更改每个请求的ip 2)注册账号,不允许账…

家居网购项目(Ajax验证用户名+上传图片)

文章目录 1.Ajax验证用户名1.程序框架图2.修改MemberServlet3.修改login.jsp4.结果展示 2.Ajax判断验证码是否输入正确1.修改MemberServlet2.修改login.jsp3.结果展示 3.Ajax添加购物车1.程序框架图2.修改CartServlet2.修改index.jsp3.解决问题—未登录直接添加购物车&#xff…

深入C语言:探索结构体的奥秘

一、什么是结构体 首先我们为什么要用到结构体? 我们都已经学了很多int char …等类型还学到了同类型元素构成的数组,以及取上述类型的指针,在一些小应用可以灵活使用,然而,在我们实际应用中,每一种变量进…

租用境外服务器,越南服务器的优势有哪些

自从中国加入世界贸易组织之后,国内经济增加速度非常快,同时越来越多的人选择去东南亚国家发展,因为当地的中国人很多,所以中国企业在当地面临着更小的文化差异。东南亚地区也是最新的经济体,互联网正处于蓬勃发展的阶…

利用栈删除数组中重复元素

先将数据排序(降序或升序) 建立一个“栈”,三种情况: 1.栈为空:压入一个元素 2.栈不为空 且 栈顶元素不等于将入栈元素:压入一个元素 3.栈不为空 且 栈顶元素等于将入栈元素:删除将压入元素…

租用马来西亚服务器:稳定高效的网络选择

马来西亚首都是吉隆坡。作为一个新兴的多元化经济国家,也属于亚洲四小龙之一。地理位置优越,中间隔着南中国海。一部分是北接泰国的位于马来半岛的西马来西亚,另一部分则是东马来西亚,在婆罗洲岛的北部。这种地理位置有利于促进该…

建筑覆膜板是干什么用的?

在现代建筑施工中,覆膜板是一种非常重要的工程材料。它俗称"模板",主要用于浇筑混凝土和钢筋结构的支撑和固定。覆膜板的质量直接关系到建筑物的施工效率和质量,因此选择一家专业、靠谱的生产厂家至关重要。 贵港市能强优品木业有限公司就是一家广西知名的建筑覆膜板…