ReentrantLock源码解读
时间:2019-06-12
本文章向大家介绍ReentrantLock源码解读,主要包括ReentrantLock源码解读使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
在看此文章前,先要了解一下上一篇文章AbstractQueuedSynchronizer
(AQS)。
ReentrantLock
ReentrantLock锁的实现分为两种(公平锁、非公平锁),默认是非公平锁。
ReentrantLock lock = new ReentrantLock();
Sync(公平锁和非公平锁都继承此抽象类)
nonfairTryAcquire(尝试获取锁)
/**
* @param acquires state的增加值
*/
final boolean nonfairTryAcquire(int acquires) {
// 获取当前线程
final Thread current = Thread.currentThread();
// 获取state,0为未被线程持有,大于0为已被线程持有
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
// 设置持有的线程为当前线程
setExclusiveOwnerThread(current);
return true;
}
}
// 【可重入】如果当前线程已经持有
else if (current == getExclusiveOwnerThread()) {
// 当前的state + acquires,在NonfairSync中,即当前state+1
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
// 为什么这里用setState,而不是compareAndSetState,因为当前线程已经持有,setState不会造成其他冲突
setState(nextc);
return true;
}
return false;
}
tryRelease(尝试释放锁)
/**
* @param releases state的增加值
*/
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
// 判断当前线程是否为持有锁的线程,【解铃还须系铃人】
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
// 释放标识
boolean free = false;
// 当state为0的时候,才表明已经没有线程持有
if (c == 0) {
// 标识可以释放
free = true;
setExclusiveOwnerThread(null);
}
// 设置state
setState(c);
return free;
}
NonfairSync(非公平锁)
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
// 如果状态为0(没有线程占用),则设置为1,此方法在AbstractQueuedSynchronizer中
if (compareAndSetState(0, 1))
// 设置当前持有的线程,此方法在AbstractOwnableSynchronizer中
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
// 试图获取锁
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
FairSync(公平锁)
unlock
public void unlock() {
sync.release(1);
}
原文地址:https://www.cnblogs.com/jarjune/p/11011302.html
- 如何利用SOTER,1个版本内完成指纹支付开发?
- Rafy 框架 - 大批量导入实体
- Rafy 框架 - 执行SQL或存储过程
- 关于activitygroup过时,用frament替换操作
- Rafy 框架 - 为数据库生成注释
- CNN预测股票走势基于Tensorflow(思路+程序)
- 路径查找器AI
- android推荐使用dialogFrament而不是alertDialog
- 自定义圆角和园边的实现
- Rafy 中的 Linq 查询支持(根据聚合子条件查询聚合父)
- 应用潜在语义分析技术将文档进行3D可视化
- 利用神经网络算法的C#手写数字识别
- fastText、TextCNN、TextRNN…这套NLP文本分类深度学习方法库供你选择
- nfc开发
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Manytasking Jmetal 代码反向解析 1_MATP 测试函数集
- PHP中的ereg()与eregi()
- Java 用反射实现实体类属性 not null 校验
- 数据结构:用实例分析ArrayList与LinkedList的读写性能
- vue-element-admin上传图片的功能
- Oracle数据误删恢复
- 用斗地主的实例学会使用java Collections工具类
- Command PhaseScriptExecution failed with a nonzero exit code问题解决
- Effective Java中构建器Builder的理解
- Java的位运算符详解实例。
- 用一个测试类简化排序算法时间复杂度的研究
- R语言之可视化(33)绘制差异基因分析统计图
- Java transient不被持久化的原因
- 举一个有趣的例子,让你轻松搞懂JVM内存管理
- gulp的使用