StampedLock知识点梳理
时间:2022-07-23
本文章向大家介绍StampedLock知识点梳理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
接下来几篇文章会对JUC并发包里面的锁工具类做下梳理,如:ReentrantLock、
ReentrantReadWriteLock、StampedLock
三种模式:
- 写锁
- 悲观读锁
- 乐观读
其中,写锁、悲观读锁的语义和 ReadWriteLock 的写锁、读锁的语义非常类似,允许多个线程同时获取悲观读锁,但是只允许一个线程获取写锁,写锁和悲观读锁是互斥的。
不同的是:StampedLock 里的写锁和悲观读锁加锁成功之后,都会返回一个 stamp;然后解锁的时候,需要传入这个 stamp。
主要方法:
- long writeLock() ,阻塞式获取写锁
- long tryWriteLock(),非阻塞式获取写锁,如果是0,表示没有拿到写锁
- long tryWriteLock(long time, TimeUnit unit),同上,支持超时时间
- long writeLockInterruptibly(),阻塞式获取写锁,支持中断
- long readLock(),阻塞式获取悲观读锁
- long tryReadLock(),非阻塞式获取悲观读锁,如果是0,表示没有拿到锁
- long tryReadLock(long time, TimeUnit unit),同上
- long readLockInterruptibly(),阻塞式获取悲观读锁,支持中断
- long tryOptimisticRead(),获取乐观读的版本号
- boolean validate(long stamp),验证上面的版本号是否通过,期间是否有修改
- void unlockWrite(long stamp) ,释放写锁
- void unlockRead(long stamp),释放悲观读锁
- void unlock(long stamp),释放锁,笼统
- long tryConvertToWriteLock(long stamp),升级读锁为写锁,非阻塞式,不满足返回0
- 其它的一些方法,主要用于监控,数据采集
特性:
- 不支持重入
- 写锁、悲观读锁都不支持条件变量
- 一定不要调用中断操作,如果需要支持中断功能,一定使用可中断的悲观读锁 readLockInterruptibly() 和写锁 writeLockInterruptibly()
与ReadWriteLock比较:
- ReadWriteLock 支持多个线程同时读,但是当多个线程同时读的时候,所有的写操作会被阻塞,可能导致写的饥饿问题(读操作一直都能抢占到CPU时间片,而写操作一直抢不了)
- StampedLock 的性能比 ReadWriteLock 好。主要是 StampedLock 支持乐观读的方式。当在乐观读期间,允许另一个线程获取写锁。那么怎样保证读和写的一致性呢?通过
validate()方法
,如果校验不通过,说明期间有修改,可以再重试一次。
乐观读,使用模板:
final StampedLock sl = new StampedLock();
// 乐观读
long stamp = sl.tryOptimisticRead();
// 读入方法局部变量
......
// 校验 stamp
if (!sl.validate(stamp)){
// 升级为悲观读锁
stamp = sl.readLock();
try {
// 读入方法局部变量
.....
} finally {
// 释放悲观读锁
sl.unlockRead(stamp);
}
}
// 使用方法局部变量执行业务操作
......
- 【LeetCode 389】 关关的刷题日记30 Find the Difference
- 1708: [Usaco2007 Oct]Money奶牛的硬币
- 1856: [Scoi2010]字符串
- 【LeetCode 409】 关关的刷题日记31Longest Palindrome
- Git的奇技淫巧?
- 3224: Tyvj 1728 普通平衡树
- 【LeetCode 136】 关关的刷题日记32 Single Number
- 1599: [Usaco2008 Oct]笨重的石子
- 【LeetCode 136】 关关的刷题日记33 Intersection of Two
- 1218: [HNOI2003]激光炸弹
- Java多线程高并发学习笔记(一)——Thread&Runnable
- 1257: [CQOI2007]余数之和sum
- 【LeetCode 136】 关关的刷题日记34 Intersection of Two Arrays II
- 1724: [Usaco2006 Nov]Fence Repair 切割木板
- 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 数组属性和方法
- Linux基础:性能监控
- pstack 跟踪进程栈
- android实现左右侧滑菜单效果
- 排查守候在零点两分的 bug
- Android中TextView实现部分文字可点击跳转
- Android viewpager自动轮播和小圆点联动效果
- 用Redis构建缓存集群的最佳实践有哪些?
- Android实现IP地址输入框的方法示例代码
- Node.js 搭建 HTTPS 服务器
- Android布局之表格布局TableLayout详解
- 简单实现Android倒计时效果
- Android实现单页面浮层可拖动view的一种方法
- 排查 Node.js 服务内存泄漏,没想到竟是它?
- Android判断网络状态的代码
- Android开发实现布局中为控件添加选择器的方法