当前位置:网站首页>ReentrantLock学习之公平锁过程
ReentrantLock学习之公平锁过程
2022-07-26 18:05:00 【virtuousOne】
ReentrantLock支持公平锁和非公平锁,默认使用非公平锁。
主要记录公平锁里面的实现
通过源码可以发现公平锁的加锁方法
模拟ReentrantLock的加锁过程。
自定义一个Lock进行实现
public interface Lock {
void lock();
void unLock();
}
在ReentrantLock实现类里面,有几个变量
/** * 0 表示未加锁状态 * > 0 表示当前lock是加锁状态 */
private int state;
/** * 独占模式 * 同一时刻只有一个县城可以持有锁,其他的线程,在为获取到锁时,会被阻塞 */
private Thread exclusiveOwnerThread;
Node封装节点,里面包含有前置节点和引用节点和线程信息
static final class Node{
// 前置节点引用
Node prev;
// 后置节点引用
Node next;
// 封装的线程本尊
Thread thread;
public Node(Thread thread) {
this.thread = thread;
}
public Node() {
}
}

在源码中,加公平锁的时候,主要是进行该段代码逻辑获取加锁
private void acquireQueued(Node node,int arg){
// 只有当前node成功获取到锁以后, 才会跳出自旋
for (;;){
//
// 1. 当前node 是head的后继节点. 才有这个权限
Node pred = node.prev;
// 当前node 拥有抢占权限
//
if(pred == head && tryAcquire(arg)){
// 这里面, 说明当前线程 竞争锁成功啦。
// 1.设置当前head 为当前线程的node
// 2. 协助原始head 出队
setHead(node);
pred.next = null ; // help GC
return;
}
// 将当前线程挂起
LockSupport.park();
}
}
private Node addWaiter(){
Node newNode = new Node(Thread.currentThread());
// 如何入队
// 1. 找到newNode的前置节点
// 2.更新newNode.prev = 前置节点
// 3. CAS更新tail为 newNode
// 4.更新pred.next = newNode
// 前置条件: 队列已经有等待者node了,当前node 不是第一个进入对的node
Node pred = tail;
if(pred != null){
newNode.prev = pred;
// 当前线程成功入队
if(compareAndSetTail(pred,newNode)){
pred.next = newNode;
return newNode;
}
}
// 1.tail == null 队列时空对象
// 2.cas设置失败了,被其他线程抢先一步了。
enq(newNode);
return newNode;
}
/** * 自旋入队,只有成功后才返回 * * 1.tail == null 队列时空对象 * 2.cas设置失败了,被其他线程抢先一步了。 */
private void enq(Node node){
for(;;){
// 第一种情况: 队列时空
// 当前线程是第一个去抢占锁失败的线程
// head节点 任何时候 都代表当前占用锁的线程
if(tail == null){
// 说明当前线程 给当前持有锁的线程 补充 head 操作成功
if(compareAndSetHead(new Node())){
//
tail = head;
// 还会继续自旋
}else {
// 说明当前队列中已经有node了,这里是一个追加node的过程
Node pred = tail;
if(pred != null){
node.prev = pred;
// 当前线程成功入队
if(compareAndSetTail(pred,node)){
pred.next = node;
return ;
}
}
}
}
}
}
在公平锁加锁的过程中,还有一段逻辑是获取锁的过程
private boolean tryAcquire(int arg){
if(state == 0){
// 条件1: 取反后值为true,表示当前线程前面没有等待者
// 条件2: lock方法可能有多线程调用,使用CAS,成立表示当前线程抢锁成功
if(!hasQueuedPredecessor() && compareAndSetState(0,arg)){
// 抢锁成功
// 1.需要将exclusiveOwnerThread 设置为当前进入的线程
this.exclusiveOwnerThread = Thread.currentThread();
return true;
}
// 当前锁被占用的时候来到此处
// 并且更新state值
}else if(Thread.currentThread() == this.exclusiveOwnerThread) {
// 里面不存在并发
// 说明当前线程为持锁线程, 需要返回true,
int c = getState();
c = c + arg;
// 越界判断
this.state = c;
return true;
}
// 什么时候返回false?
// 1.CAS加锁失败
// 2.state > 0 且 当前线程不是占用者线程
return false;
}
边栏推荐
- Distributed transaction Seata
- Kubectl common commands and simple explanations
- MongoDB stats统计集合占用空间大小
- js map使用
- 2022T电梯修理考试题及在线模拟考试
- Daorayaki | product principles of non-financial decentralized application
- 实用工具网站推荐
- How many pairs can an array of leetcode simple questions form
- Leetcode notes: Weekly contest 303
- Is it safe to apply for public REITs account by mobile phone?
猜你喜欢

Operations research 69 | explanation of classic examples of dynamic planning

篇7:exited on DESKTOP-DFF5KIK with error code -1073741511.
![[MySQL from introduction to proficiency] [advanced chapter] (VIII) clustered index & non clustered index & joint index](/img/18/1644301d575fad0a0d0f15932487d0.png)
[MySQL from introduction to proficiency] [advanced chapter] (VIII) clustered index & non clustered index & joint index

Tensor Rt的int8量化原理

Daorayaki | product principles of non-financial decentralized application

The first letter of leetcode simple question appears twice

基础模块及算例#pytorch学习

SSM integration - functional module and interface testing

2022年流动式起重机司机考试试题模拟考试平台操作

JS刷题计划——数组
随机推荐
Brand new! Uncover the promotion route of Ali P5 Engineer ~p8 architect
MySQL - 函数及约束命令
Current occupation, write later
Covos: no need to decode! Semi supervised Vos acceleration using motion vectors and residuals of compressed video bitstreams (CVPR 2022)
Seata 入门简介
[MySQL from introduction to proficiency] [advanced chapter] (VIII) clustered index & non clustered index & joint index
Paged query design of scenarios
JS map usage
Is it safe to apply for public REITs account by mobile phone?
This section is used to supplement 3
SSM integration configuration
Leetcode simple question: the minimum total time required to fill a cup
[swoole series 3.1] have you been asked about processes, threads, and collaborations during the interview?
模板进阶(跑路人笔记)
当前占位,之后再写
Write a thesis and read this one
js map使用
JS刷题计划——数组
Utility website recommendations
VTK (the Visualization Toolkit) loads STL models