当前位置: 首页 > news >正文

公平锁和非公平锁,我学了好几次才记住它们的区别

学并发编程的时候,"公平锁"和"非公平锁"这两个概念我反复读了好几遍。每次看的时候好像懂了,合上书又说不清楚。后来我决定自己写一遍,写着写着好像真的记住了。

写下来给自己看,也分享给正在学的你。

先说公平锁——它的问题在哪

公平锁,顾名思义,就是"先来后到"。谁先来排队,锁就归谁。

听起来挺合理的对吧?但代价藏在细节里。

第一个问题是,线程的挂起和唤醒很重。

公平锁释放锁的时候,要去唤醒排在队列最前面的那个线程。那个线程之前可能已经休眠了,现在要把它叫醒。叫醒一个线程,不是简单拍它一下说"嘿,该你干活了",而是操作系统在幕后做一大堆事情:从用户态切换到内核态,保存当前上下文,再恢复目标线程的上下文。这个过程叫上下文切换(Context Switch),每一次都很贵。

第二个问题是,CPU 缓存白费了。

线程被挂起之后,它之前在 CPU 缓存(L1、L2、L3)里存的数据大概率就失效了。等它重新被调度回来执行,又得从主内存重新加载数据。就像你正在看书,被人叫出去等了一个小时再回来,刚才看到哪一行、讲了什么都忘了,得重新翻。

第三个问题更隐蔽——锁释放了,但没人用。

从锁释放到被唤醒的线程真正拿到 CPU 开始执行,中间有一个时间差。这个时间差里锁是空着的,没有人用它。等于是餐厅门口排队的顾客被叫到了,但走过去还要十几秒,这十几秒柜台是空的。

这三个问题叠在一起,结果就是:公平锁的吞吐量上不去,因为它把大量 CPU 时间花在了"调度"这件事本身,而不是让线程真正干活。

再说非公平锁——它为什么快

非公平锁说白了就是允许"插队"。

线程来请求锁的时候,先不管队列里有谁在排队,直接用 CAS(Compare And Swap,一种轻量级的原子操作)试一次——如果锁刚好是空闲的,就直接拿到手了,管它排不排队。

这个"先试一下"的机制带来了四个好处。

第一,很多线程根本不用进入等待队列。运气好的时候,锁刚释放你就到了,一把就拿到了。省去了从运行到挂起、再从挂起到唤醒的完整流程。

第二,上下文切换的次数大幅减少。因为大量线程没有经历"挂起→唤醒"这个最贵的过程,操作系统不需要来回切用户态和内核态了。

第三,CPU 缓存热度保持得好。线程没有休眠,一直处于运行状态,它缓存里的数据还是热的。同样是执行一段代码,缓存命中和缓存失效的差别可能就是几倍甚至几十倍。

第四,没有调度延迟。锁释放之后,下一个线程是已经活跃着的,可以直接抢到锁继续跑,不需要等操作系统把一个休眠的线程叫醒。锁的流转更紧凑,空闲时间被压到了最低。

所以,选哪个?

公平锁和非公平锁,本质上是公平效率之间的取舍:

  • 公平锁:线程永远不会饿死,每个线程最终都能拿到锁。代价是整体吞吐量下降。
  • 非公平锁:吞吐量高,但代价是可能出现极少数线程"运气不好",被后面的线程反复插队,导致它等待的时间比理论上要长。

不过在实际中,非公平锁的这种"饥饿"概率其实很小,尤其是锁竞争不是很极端的情况下,基本感觉不到。所以像ReentrantLock默认就是非公平模式,不是没有道理的。

最后

写完之后我发现,所谓"学懂了",其实就是能用自己的话把这些东西说清楚。不用排比,不用金句,白描就行了。

上面如果有哪里写得不准确或者啰嗦了,欢迎指出来——毕竟我也是学着写的。

http://www.jsqmd.com/news/1084000/

相关文章:

  • 小红书种草笔记的CES评分机制深度拆解——从算法逻辑到实操提分
  • Python+Selenium自动化测试:Chrome Driver版本管理全流程实现
  • 从CTF实战解析SQL注入:绕过过滤与联合查询攻防
  • 2025年网盘直链下载工具深度解析:LinkSwift如何提升你的下载体验
  • XSS攻击全解析:从原理到防御的Web安全实战指南
  • 6月24日豆包上线专业版!办公任务模式实测惊艳,2亿用户开启AI普惠办公新时代
  • 天行健与优胜劣汰:两种文明范式的哲学比较及其现代启示
  • Java基础进阶:位运算体系与字符串底层原理全解析
  • 如何让老旧Mac焕发新生?OpenCore Legacy Patcher终极指南
  • n8n表达式注入漏洞CVE-2025-68613:从原理到RCE的深度剖析与防御
  • 国产化视频会议安全加密:从国密算法到端到端加密的实战解析
  • 版权知识小科普:这些你一定要知道
  • 大模型微调算力选型:8 路 RTX 5090 服务器与单张 A100 80GB 性能、显存、成本场景对比
  • AI算力行情轮到玻璃基板,巨头布局加速商业化,量产还有哪些难关?
  • 北京时间与不同时区时间:来历、介绍与用途
  • 微信私域如何告别“拍脑袋决策”?从 WecomApi 拆解大规模 A/B 测试与增长实验中台架构
  • XXE漏洞深度解析:原理、利用与多语言防御实战
  • 实战指南:解锁Joy-Con手柄自定义功能的完整工具包
  • 文件上传漏洞攻防实战:从绕过检测到Webshell获取
  • 天河应用大讲堂 | 基于人工智能的天气预报技术发展趋势
  • LSR包胶技术深度解析:金属包胶、塑料包胶到底怎么做?
  • 打通企微接口,构建适配 GEO 检索规则的结构化素材库
  • 100个RPG Maker MV插件:零代码打造专业级游戏体验
  • OpenAI 9 个月自研芯片 Jalapeño,推理成本砍半,ChatGPT 体验将大升级!
  • 自动整形设备中的接近开关:让变形件回到标准位置
  • 从安装到调优,Strix Halo 本地大模型一周使用实录
  • C++跨平台(一):开发概述与策略选择
  • 终极指南:如何用ExtractorSharp高效编辑NPK游戏资源文件
  • 【Springboot毕设全套源码+文档】基于SpringBoot+Vue的学生交流互助平台的设计与实现(丰富项目+远程调试+讲解+定制)
  • 揭秘Wireshark:为什么它是全球第一的开源抓包工具?