Java常见技术分享-13-多线程安全-锁机制-底层核心实现机制

我觉得吧, 没必要因为不懂而感到羞耻, 不懂就去学呗 一天学不会就再来一天喽, 总有一天会明白的,所以大胆的承认自己的无知吧, 然后去追寻答案

锁的基础核心实现(两大核心)
CAS(compare and swap)

首先记住CAS 是 乐观锁 (乐观策略) 的核心实现。

阻塞与唤醒

这是悲观锁 (悲观策略)的核心实现。

上一篇章我们学习了锁的分类, 要知道所有分类的锁 , 底层最终只依赖这两种核心的实现手段, 这是根基, 不管什么维度的锁, 本质上都是这两种手段的单独使用或组合使用, 掌握它能一通百通。 也是面试的核心。 这一篇章, 我们就只聚焦这两个核心他们的以下三个知识点

  • 熟悉核心流程
  • 优缺点
  • 存在的核心问题以及解决方案

CAS

核心流程

1 . 首先核心3参数, 内存地址V, 预期旧值 A, 目标新值 B。

  1. 线程读取内存地址V 存储的 当前值 是否与 预期旧值 A 一致, 如果一致 , 则用 CAS原子命令 将 内存地址V存储的值 更新 为目标新值, 返回成功 。

  2. 不一致 ,则更新失败, 直接失败 或者 自旋重试(业务侧更新预期旧值 以及 重新计算 目标新值B 再重新尝试CAS流程)

优点

无上下文切换开销, 当并发冲突少时, 性能极高。

基于CPU原子指令 实现, 无需依赖OS 即 操作系统, 属于用户态的操作, 响应快。

缺点

当并发冲突高时, 自旋会持续占用CPU资源, 导致CPU飙升。

仅能保证单个变量操作的原子性, 多个变量就没法支持了。

核心问题 + 解决方案
  • 问题1 : ABA问题(内存地址V存的值从1 -》 2 -》 1 , 对于执行CAS操作 预期旧值是1 的线程, 误判为没变)
  • 解决方案 : 版本号机制, 比对值+ 版本号
  • 问题2 : 高竞争下自旋浪费CPU
  • 解决方案 : 自适应自旋 , 就是 通过一些指标判断当前环境竞争大与否, 如果大 , 同一时间的自旋次数少, 反之, 自旋次数多。
  • 问题3: 单变量原子性局限
  • 解决方案: 结合锁(如 synchronized ) , 拆分业务逻辑, 或把 多个变量封装成一个对象 使用AtomicReference.

阻塞唤醒

核心流程
  1. 线程竞争失败
  2. 放弃CPU执行权, 进入阻塞状态(waiting / timed_waiting),移出CPU调度队列
  3. 持有锁 线程 释放锁时, 唤醒阻塞队列中 等待线程
  4. 被唤醒的线程 重新进入 就绪队列
  5. 等待CPU调度后 再次竞争锁
优点

并发冲突高时, 线程由于直接阻塞, 所以就不会占用CPU资源, 也就不会浪费CPU资源。

支持多变量, 复杂逻辑的线程安全, 使用场景更广。

缺点

线程阻塞 / 唤醒 , 涉及 用户态 -》 内核态(OS) -》 用户态 切换,主要是在这过程中上下文切换开销大。 且线程被唤醒后,存在CPU调度的延迟, 响应不如 CAS。

核心问题 + 解决方案
  • 问题1 : 阻塞唤醒开销大
  • 解决方案: 前置CAS 优化, 比如synchronized 先 自旋CAS , 失败再则色, 来减少阻塞的概率。
  • 问题2 : 线程唤醒后 ,竞争锁 ,仍可能失败(惊群效应)
  • 解决方案 : 这种有两种方案 一种用公平锁, 确保拿锁线程的顺序, 另一种方案 则是 重试一定次数之后, 直接失败处理, 不重试了。
  • 问题3 : 死锁风险
  • 解决方案: 避免锁的循环依赖, 按照固定顺序 加锁, 设置锁超时。
补充一下-死锁的四个必要的条件
  1. 一个锁只能被一个线程占用
  2. 请求与保持, 请求新的锁, 保持对已有的锁的占用
  3. 不可剥夺, 线程占用的锁不能被强行剥夺。
  4. 循环等待, 多个线程构成了一个循环链。
相关推荐
无巧不成书02181 分钟前
Unicode编码机制全解析:从核心原理到Java 实战
java·开发语言·java字符编码·unicode 15.1码点
楼田莉子2 分钟前
设计模式:构造器模式
开发语言·c++·后端·学习·设计模式
lly2024063 分钟前
Swift 析构过程
开发语言
mu_guang_5 分钟前
计算机体系结构3-cache一致性和内存一致性的区别
java·开发语言·计算机体系结构
海兰8 分钟前
使用 Spring AI 打造企业级 RAG 知识库第一部分:核心基础
java·人工智能·spring
lingggggaaaa10 分钟前
PHP模型开发篇&MVC层&动态调试未授权&脆弱鉴权&未引用&错误逻辑
开发语言·安全·web安全·网络安全·php·mvc·代码审计
恼书:-(空寄11 分钟前
责任链模式实现流程动态编排
java·责任链模式
星原望野11 分钟前
java:volatile关键字的作用
java·开发语言·volatile
APIshop16 分钟前
Java获取淘宝商品价格、图片与视频:淘宝开放平台API实战指南
开发语言·python
XiYang-DING18 分钟前
【Java】Map和Set
java·开发语言