JAVA基础:lock锁底层机制

目录

lock锁底层机制

乐观锁


lock锁底层机制

lock锁底层使用的是CAS + AQS,在lock底层有一个计数器,记录锁被获取的状态,起初为0 , 当被抢占的时候变为1

当我们调用lock.lock()方法,就是将状态从0改为1的过程。当我们调用lock,unlock()方法时,就是将状态从1改为0的过程

当我们调用lock.lock方法时,如果发现状态是1,表示锁被占用,当前线程进入等待状态

当多个线程同时访问lock.lock()方法时,每个线程都尝试着将状态从0改为1. 假设a线程最先完成状态改变,a线程获得了锁。此时b线程也尝试将0改为1,先获得原始值0,将0改为1,再将改好的1替换原始值0(赋值)

在替换前,会拿着之前的原始值与现在变量里的值进行比较,看看是否发生了变化

如果没有变化,说明这个过程中没有其他线程访问资源,将其改为1获得锁。

如结发生了变化,说明这个过程中被其他线程捷足先登了,其他的线程获得锁,当前线程等待

我们称这个过程为 CAS (compare and set)

当一个线程获得锁时,发现锁已经被占用了,当前这个线程就会处于等待状态

实际上,并不是线程对象有一个状态码,改为等待状态的值。

而是将需要等待的线程,存入了一个集合,并使其进入最终等待状态(jvm级别的等待状态)

当最开始线程执行完毕释放锁后,就会从这个集合中取出最开始的那个线程继续执行

这个集合我们就称为 AQS (抽象的)队列同步器

乐观锁

乐观锁不是一种真正存在的锁,一种机制

底层使用的是 CAS + 自旋 应用组合

假设线程1获得count值为0并记录为原始值

接着会对0实现++操作,变成1

接着会尝试将1赋值回count变量中

然后会根据之前记录的原始值0 与此时count变量中的值比较

如果相等,说明这个过程中没有其他线程修改count值,表示这段时间当前线程占有这个变量

完成赋值

如果不相等。比如count已经=2了,说明这个过程中,有其他线程使用过这个变量

如果继续赋值,影响了其他线程的操作结果,所以不能赋值,此次操作失败

重新获取现在的最新的值,记录为原始值2,重复操作 ,直到能够完成赋值位置

我们称这个重复过程为:自旋

相关推荐
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 14 章 MCP 服务端(上):注解式实现与工具来源
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 15 章 MCP 服务端(下):三种协议形态、Streamable 传输与状态管理
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 16 章 向量存储(上):`VectorStore` 接口体系、`BatchingStrategy`
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 12 章 工具循环的流式形态、Usage 累加与扩展体系
java·人工智能·开源
鶴哥只手遮天2 小时前
Spring AI 2.0.1 深度解析-第 23 章 模型供应商实现:从 `OpenAiSetup` 到 Bedrock
java·人工智能·开源
鶴哥只手遮天3 小时前
Spring AI 2.0.1 深度解析-第 06 章 内置 Advisor 全景:13 个实现逐个剖到源码级
java·人工智能·开源
鶴哥只手遮天3 小时前
Spring AI 2.0.1 深度解析-第 03 章 消息体系与 Prompt:不可变模型、`ChatOptions` 与模板渲染
java·人工智能·开源
鶴哥只手遮天3 小时前
Spring AI 2.0.1 深度解析-第 24 章 生产实践与 2.x 迁移:陷阱清单、AOT 与调优
java·人工智能·开源
鶴哥只手遮天3 小时前
Spring AI 2.0.1 深度解析-第 10 章 工具调用(中):执行链路、结果转换与工具限制
java·人工智能·开源
鶴哥只手遮天3 小时前
Spring AI 2.0.1 深度解析-第 13 章 MCP 客户端:传输、工具聚合与命名冲突
java·人工智能·开源