网站首页 > 博客文章 正文
一、思考人生的多线程
我们一直在说高并发、多线程、分布式应用,但是高并发情况下,多线程一定就快吗?
我们首先要理解下并发运行是怎么一回事。
为什么一般意义上来说多线程就能抵抗高并发,运行速度就能得到提升?
所谓并发运行就是某个时间段CPU能执行多个任务。
例如早上起来后,刷牙、照镜子、思考这复读机一般的人生是为哪般?
但是我们真的能同时做这么多事吗?
不是的,其实是在大脑下达指令后,刷牙、照镜子这种动作已经形成了肌肉记忆、固定动作,然后我们又有了几分钟思考人生的时光了。
同样的道理放在计算上也是一样。
我们首先要明白一个基础知识,计算机的主要组件为CPU、内存、磁盘;而在这三大组件中,CPU的运行速率高于内存1000倍以上,内存的运行速率高于磁盘1000倍以上。
当然,这只是我的口嗨,并不是真的1000倍。
你只要知道他们的运行速率对比,CPU > 内存 > 磁盘就好了,并且要快很多。
二、应付多个婴儿的哺乳妈妈
2.1 上下文切换
多线程执行就像是很多个婴儿跟妈妈要奶喝一样,怎么办?妈妈就两个哺乳器官啊?最多就同时处理两个婴儿同时肚子饿的任务。
这已经是双核CPU了。实际上,妈妈只能同时处理一个婴儿哺乳的任务而已,没办法同时把两个孩子抱在怀里。你以为是母猪可以同时喂很多小猪呢?
所以只好让婴儿先喝点,抵抵饱,哄一哄,然后换另外的孩子。
这就是CPU的【上下文切换】。
2.2 线程争用
而很多时候,我们需要运行的任务并不是一样的。
还是以婴儿为例,婴儿们同时大哭,要求占用妈妈的时间,ABC婴儿要换尿布、DEF婴儿要喝奶。
怎么办?头大。
这就是【线程争用】。
2.3 并发执行
妈妈要开始安抚孩子了,但是只能一个个来啊,要么先找几个奶瓶冲奶让要喝奶的自己抱奶瓶喝奶,再去处理换尿布。
要么先去处理尿布,再去冲奶。
冲奶这个动作很快,但是喝奶的时间很长。妈妈考虑了下,决定先冲奶,然后让他们自己抱奶瓶。
这就是【并发执行】。
2.4 自旋锁
但是冲奶的时候,婴儿还在哭,等待着妈妈送来奶瓶和换尿布怎么办?
这就是【自旋锁】。如果CPU一直不处理任务,就循环等待,直到CPU来处理。
2.5 互斥锁
如果妈妈冲奶时,抱了一个婴儿在怀里哄着不哭,其他的婴儿们没指望了,就不哭了(当然,实际上不可能),等着妈妈空出手来又继续哭,竞争妈妈的怀抱(笑)。
这就叫【互斥锁】。它跟自旋锁类似,不同的是竞争不到锁的线程会回去睡会觉,等到锁可用再来竞争。竞争失败者继续回去睡觉直到再次接到通知。
2.6 乐观锁
如果DEF拿到了奶瓶就不哭了,直到一瓶奶喝完还是喝不饱,才开始哭,要妈妈。这叫【乐观锁】。
乐观锁在数据库的数据操作中,就是提交更新那一刻,才给相关数据行加锁。
2.7 悲观锁
如果DEF拿到了奶瓶还是哭,因为他们还需要妈妈抱着喝才行。这叫【悲观锁】。
悲观锁就是如果一个事务操作用了锁,那只有当这个事务把锁释放(把妈妈给释放),其他事务才能够执行与该锁冲突的操作。
2.8 时间片分配算法
我们观察以上的故事,可以发现它们并不是同时运行的。
而CPU相比妈妈来说,它的执行速度就更快了,它通过给每个线程分配CPU时间来实现任务运行,这个时间片一般是几十毫秒。
这样不停地来回切换任务,运行程序,划分时间片,就叫做【时间片分配算法】。
2.9 线程与进程
上面说的是一个哺育室的故事,以JAVA而言,这就是一个【进程】。
如果妈妈还管着另一个哺育室,就又是一个进程。
一个哺育室有很多婴儿,婴儿们也可以认为是一个个线程。
所以【一个进程可以包含多个线程】。
而婴儿们又享受着哺育室的公共环境与玩具。这就是【内存环境共享】。
在Java应用中,每个线程都是运行在进程的上下文中,共享【同样的代码和全局数据】。
如果其中一个哺育室的装修风格、哺育规则变了,也不会影响到另一个哺育室。
所以在多进程环境中,任何一个进程的终止,都不会影响到其他进程。
所以在单核CPU时代,我们在一台电脑上也可以同时听歌、写作,可以一边看电影、一边论坛灌水【多进程】,而一个论坛里又可以有多个用户同时灌水【多线程】。
三、多线程一定比单线程跑得快吗?
回到最初的话题。
面试官:
如果有很多任务,每个任务需要CPU处理的时间都很长,占用的时间片很高,那么,多线程还能快吗?
如果任务很少的情况下又是怎么样呢?
例如只有两个婴儿,来回换着哺乳快还是一个个喂饱来得快呢?
什么情况下适合使用多线程呢?
除了CPU、内存、磁盘,还有什么能影响并发执行的速度呢?
如果你是面试者,怎么回答呢?留言给我说说看你的看法。
如果你对我上面的解释并不满意,有着不同的看法,也欢迎来喷一喷。
读者福利:我把近一年经历过的Java岗位面试,和一些刷过的面试题都做成了PDF,PDF都是可以免费分享给大家的,只要关注私信我:【101】,就能获取免费领取方式!
- 上一篇: 详解并发、多线程、HTTP连接数之间的关系
- 下一篇: 并发和并行的区别图解(一文彻底搞懂)
猜你喜欢
- 2024-10-07 JS和C#/JAVA的多线程,究竟有什么不一样?
- 2024-10-07 什么是多线程?看我多线程七十二变,你能记住吗?
- 2024-10-07 【多线程与高并发】- 浅谈volatile
- 2024-10-07 精通高并发与多线程,却不会用ThreadLocal?
- 2024-10-07 【程序员课堂】多线程、进程和线程的区别
- 2024-10-07 了解架构设计远远不够!一文拆解 Tomcat 高并发原理与性能调优
- 2024-10-07 爬虫入门必学:多线程与多进程的区别
- 2024-10-07 【开发者成长】深入理解多线程编程
- 2024-10-07 python中多线程与多进程的区别(python多进程和多线程协程)
- 2024-10-07 搞懂分布式与高并发,看这篇就够了
你 发表评论:
欢迎- 07-08Google Cloud Platform 加入支持 Docker 的容器引擎
- 07-08日本KDDI与Google Cloud 签署合作备忘录,共探AI未来
- 07-08美国Infoblox与Google Cloud合作推出云原生网络和安全解决方案
- 07-08GoogleCloud为Spanner数据库引入HDD层,将冷存储成本降低80%
- 07-08谷歌推出Cloud Dataproc,缩短集群启动时间
- 07-08Infovista与Google Cloud携手推进射频网络规划革新
- 07-08比利时Odoo与Google Cloud建立增强合作,扩大全球影响力
- 07-08BT 和 Google Cloud 通过 Global Fabric 加速 AI 网络
- 最近发表
-
- Google Cloud Platform 加入支持 Docker 的容器引擎
- 日本KDDI与Google Cloud 签署合作备忘录,共探AI未来
- 美国Infoblox与Google Cloud合作推出云原生网络和安全解决方案
- GoogleCloud为Spanner数据库引入HDD层,将冷存储成本降低80%
- 谷歌推出Cloud Dataproc,缩短集群启动时间
- Infovista与Google Cloud携手推进射频网络规划革新
- 比利时Odoo与Google Cloud建立增强合作,扩大全球影响力
- BT 和 Google Cloud 通过 Global Fabric 加速 AI 网络
- NCSA和Google Cloud合作开发AI驱动的网络防御系统,加强泰国网络空间的安全性
- SAP将在沙特阿拉伯 Google Cloud 上推出BTP服务
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- googlecloud (64)
- messagesource (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)