当前位置:网站首页>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;
}
边栏推荐
- JS使用readline来实现终端输入数据
- 网络协议:TCP/IP协议
- Support proxy direct connection to Oracle database, jumpserver fortress v2.24.0 release
- 2022年焊工(初级)操作证考试题库及模拟考试
- .net CLR GC dynamic loading transient heap threshold calculation and threshold excess calculation
- 2022年制冷与空调设备运行操作考试模拟100题及模拟考试
- Zbxtable 2.0 heavy release! 6 major optimization functions!
- Complete MySQL database commands
- Gongfu developer community is settled! On July 30!
- JS map usage
猜你喜欢

NFT digital collection system development: fellow uncle first promoted the blessing series digital collection, which will be sold out immediately

详细介绍@GetMapping和@PostMapping的区别

Database expansion can also be so smooth, MySQL 100 billion level data production environment expansion practice

自动化测试的使用场景

CTO will teach you: how to take over his project when a technician suddenly leaves

MySQL - 多表查询与案例详解

The class jointly built by famous oarsmen is new, and Professor qiuxipeng of Fudan University broadcast it live on Tuesday!

Write a thesis and read this one

Daorayaki | product principles of non-financial decentralized application

Introduction to Seata
随机推荐
Huawei cloud · cloud sharing experts~
2022t elevator repair examination questions and online simulation examination
MES系统最全介绍来了
网络协议:TCP/IP协议
TypeScript阶段学习
最后一篇博客
Article 7:exited on desktop-dff5kik with error code -1073741511
MySQL学习笔记-2.如何提高sql语句的查询性能
2022g1 industrial boiler stoker certificate question bank and simulation examination
【考研词汇训练营】Day 14 —— panini,predict,access,apologize,sense,transport,aggregation
2022年流动式起重机司机考试试题模拟考试平台操作
2022 mobile crane driver test questions simulation test platform operation
Leetcode simple question: the minimum total time required to fill a cup
LeetCode简单题之验证回文字符串 Ⅱ
2022 welder (elementary) operation certificate examination question bank and simulation examination
Multi merchant mall system function disassembly Lecture 16 - platform side member growth value record
Kubectl common commands and simple explanations
SD NAND与eMMC优劣势对比
In this competition, you who can understand the topic have great potential
VPC nat (Sant, nant) experiment