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. 循环等待, 多个线程构成了一个循环链。
相关推荐
曹轲恒3 小时前
Java中断
java·开发语言
xxxmine3 小时前
Java并发wait(timeout)
java
冰冰菜的扣jio4 小时前
Redis缓存问题——一致性问题、事务、持久化
java·spring·mybatis
施棠海4 小时前
监听与回调的三个demo
java·开发语言
時肆4854 小时前
C语言造轮子大赛:从零构建核心组件
c语言·开发语言
赴前尘4 小时前
golang 查看指定版本库所依赖库的版本
开发语言·后端·golang
de之梦-御风4 小时前
【C#.Net】C#开发的未来前景
开发语言·c#·.net
毕设源码-钟学长4 小时前
【开题答辩全过程】以 家政服务平台为例,包含答辩的问题和答案
java
知乎的哥廷根数学学派5 小时前
基于数据驱动的自适应正交小波基优化算法(Python)
开发语言·网络·人工智能·pytorch·python·深度学习·算法
de之梦-御风5 小时前
【C#.Net】C#在工业领域的具体应用场景
开发语言·c#·.net