JDK1.8 邮戳锁(StampedLock)知识点整理以及示例
邮戳锁时JDK1.8版本后引入的一种锁机制,与ReentrantRead-WriteLock类似,该锁可以用于控制读写访问。
public class StampeLock extends Object implements Serializable
邮戳锁的状态由版本号和模式两个部分组成,通过三种模式控制读、写操作,这三种模式分别如下:
1)写模式。如果线程调用writeLock()获取邮戳锁,如果该已经被其他对象持有,则该线程阻塞,等待对象释放该锁,线程在获得该锁时,会获得一个长整型的值,该值在解锁的时候作为参数使用。该锁在写模式下,不会获得读锁,其他的乐观锁也会失效。
2)读模式。使用方法readLock();在获取该该锁时,也会获取一个长整型的数值,该值在在解锁时作为参数使用。该锁在等待非排他性访问时有可能被阻塞。该模式也提供了tryReadLock()方法,用于获取读锁。
3)乐观读模式。乐观读模式可以被看成是读模式的另一个版本,它可以在任何时刻被一个试图写入的线程打断,进入写模式。 当代码长度短并且对数据的操作为只读时,非常适合乐观读模式,它可以减少竞争,提高程序的吞吐量。然而,乐观读模式又非常脆
弱,很容易被打打断从而进入其他的模式。当处于乐观读模式时,代码部分应该只读类的属性,并且经过验证(使用方法validate())后把类的属性放入一个本地变量中供以后使用,属性的读操作在乐观读模式下很可能会导致不一致,所以只有对数据表示足够熟悉
时才能应用,并且要反复使用validate()方法来检查一致性。
example:
当程序第一次读到一个对象引用,然后马上访问该对象引用的某一个属性时,这种情况就需要调用validate()方法。当邮戳没有处于写模式时,调用tryOptimisticRead()方法会返回一个非零值stamp,stam值被视作为锁的一中状态。
当所在写模式下并且锁没有被其他线程持有,validate()方法将返回true,说明已经成功转为乐观读模式。
锁获取方法将返回一个长整型的邮戳stamp,该邮戳值用于表示锁的一个状态,并进行控制访问。带有try的锁获取方法(例如tryOptimisticRead())可能会返回特殊的值0;表示尝试获取锁失败。
锁的释放和转换是需要使用stamp作为参数,当没有匹配锁的状态将释放和转换失败。
StampedLock类中提供了一些方法,可以用于在三种模式中进行转换,
例如:
方法tryConvertToWriteLock(long stamp)将会尝试转换为写模式,并且当满足以下条件时将返回一个有效的写模式的stamp。
1)已经处于写模式;
2)在读模式下,并且已经没有其他线程读。
3)在乐观读模式下,没有被锁定。
邮戳锁通常作为内部工具用于线程安全的组件开发过程中,但需要根据处于临界区内的数据属性,对象及其方法决定如何使用邮戳锁。
注意事项:
邮戳锁是不可重入的,所以被邮戳锁保护的临界区内不应该含有对其它有可能重新获取该锁的方法调用,否则会一起死锁。
例如:
StampedLock slock = new StampedLock();
public void compute(){
long stamp = slock.writeLock();
try{
output();
}finally{
slock.unlockWrite(stamp);
}
}
public void output(){
long stamp = slock.readLock();
try{
//.......
}finally{
slock.unlockWrite(stamp);
}
}
在方法compute()中调用了方法output();则运行时会一起死锁。
/**
* 启动类
* @author YeDong
*
*/
public class Index {
public static final int N = 10;
public static void main(String[] args) {
IntList ilist = new IntList();
int rnumber = 5;
int wnumber = N-rnumber;
Thread [] rt = new Thread[rnumber];
Thread [] wt = new Thread[wnumber];
ilist.fillIfEmpty();
System.out.println("开始生成"+rnumber+"个读线程>>>>>>");
for(int i=0;i<rnumber;i++) {
rt[i] = new ReadThread(ilist);
rt[i].start();
}
System.out.println("开始生成"+rnumber+"个写线程>>>>>>");
for(int i=0;i<rnumber;i++) {
wt[i] = new WriteThread(ilist);
wt[i].start();
}
System.out.println("执行完毕!");
}
}
-----------------------------------------------------------------------------------------------
/**
* 初始化测试的List 并对其进行数据操作
*/
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.StampedLock;
public class IntList {
List<Integer> intList;
StampedLock sl;
public IntList() {
intList = new ArrayList<Integer>();
sl = new StampedLock();
}
//使用写模式向List添加数据
public void insert(int num) {
long stamp = sl.writeLock();
try {
intList.add(num);
}finally {
sl.unlockWrite(stamp);
}
}
//使用读模式读取List集合中的数据
public int get(int index) {
long stamp = sl.readLock();
try {
return intList.get(index);
} finally {
// TODO: handle finally clause
sl.unlockRead(stamp);
}
}
//使用尝试读方法 读取数据
public int getOptimisticRead(int index) {
long stamp = sl.tryOptimisticRead();
int temp = intList.get(index);
if(!sl.validate(stamp)) {
stamp = sl.readLock();
try {
temp = intList.get(index);
} finally {
// TODO: handle finally clause
sl.unlockRead(stamp);
}
}
return temp;
}
//将读模式升级为写模式
public void fillIfEmpty() {
long stamp = sl.readLock();
try {
while(intList.isEmpty()) {
long ws = sl .tryConvertToReadLock(stamp);
if(ws!=0) {
stamp = ws;
for(int i=0;i<50;i++) {
intList.add(i);
}
}else {
sl.unlockRead(stamp);
sl.writeLock();
}
}
} finally {
sl.unlock(stamp);
}
}
}
----------------------------------------------------------------------------------------
/**
* 读取数据的线程
* @author YeDong
*
*/
public class ReadThread extends Thread{
IntList iList;
public ReadThread(IntList iList) {
super();
this.iList = iList;
}
public void run() {
for(int i=0;i<50;i++) {
//iList.get(i);
iList.getOptimisticRead(i);//优化
}
}
}
-------------------------------------------------------------------------------------------
/**
* 写入数据的线程
* @author YeDong
*
*/
public class WriteThread extends Thread {
IntList iList;
public WriteThread(IntList iList) {
super();
this.iList = iList;
}
public void run() {
for(int i=0;i<50;i++) {
iList.insert(i);
}
}
}
JDK1.8 邮戳锁(StampedLock)知识点整理以及示例相关推荐
- 读写锁之ReentrantReadWriteLock与邮戳锁StampedLock知识总结
ReentrantReadWriteLock 读写锁ReentrantReadWriteLock下,一个资源可以被多个读线程访问或一个写线程访问,但不能同时存在读写线程,也就是读读共享,读写互斥.多线 ...
- CSS知识点整理(代码示例参考w3shool)(包括CSS概念语法作用、CSS引入方式、CSS背景、文本、字体、链接、轮廓、表格、常用选择器等)
文章目录 CSS简介 CSS 概念 CSS 作用 CSS 语法 CSS引入方式 1.内联样式表 2.内部样式表 3.外部样式表 CSS常用样式 CSS背景 1.背景色:background-color ...
- JUC-9.“锁”事(显式锁与隐式锁/悲观锁与乐观锁/公平锁与非公平锁/可重入锁/读写锁(独占/共享/降级)/邮戳锁/死锁)、锁升级
目录 一.悲观锁与乐观锁 1.1 悲观锁 1.2 乐观锁 二.公平锁与非公平锁 2.1 为什么会有公平锁/非公平锁的设计为什么默认非公平? 2.2 如何选择使用哪种锁? 三.可重入锁(又名递归锁) 3 ...
- JUC并发编程第十四篇,StampedLock(邮戳锁)为什么比ReentrantReadWriteLock(读写锁)更快!
JUC并发编程第十四篇,StampedLock(邮戳锁)为什么比ReentrantReadWriteLock(读写锁)更快! 一.ReentrantReadWriteLock(读写锁) 1.读写锁存在 ...
- StampedLock邮戳锁
文章目录 StampedLock是什么 由锁饥饿问题引出StampedLock 如何缓解锁饥饿问题? 1 使用"公平"策略可以一定程度上缓解这个问题 2 StampedLock类的 ...
- 06-JAVA面试核心知识点整理(时间较多的同学全面复习)
JVM (1) 基本概念: JVM是可运行Java代码的假想计算机 ,包括一套字节码指令集.一组寄存器.一个栈.一个垃圾回收,堆 和 一个存储方法域.JVM 是运行在操作系统之上的,它与硬件没有直接的 ...
- 面试题引出的知识点整理
1.自旋锁&可重复锁&公平锁&共享锁&分段锁你都知道吗? 2.无锁&偏向锁&轻量级锁&重量级锁如何膨胀升级? 3.Lock底层AQS实现与Syn ...
- Java基础知识点整理(2022年最新版)
看了网上很多关于Java基础知识点整理的文章,但是感觉都不是很好,要么不全面,要么不准确,要么排版太乱了,所以今天整理了一份Java基础知识点整理(2022年最新版),希望对大家有帮助哈~ 由于本文篇 ...
- 大数据——Java 知识点整理
1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java开发工具包,提供了java的开发环境和运行环境. JRE:Java Runtime Envir ...
最新文章
- python身份运算符的语法规则_7 Python语法入门之与用户交互、运算符
- 我的mongo学习之路
- oracle常见单词_Oracle的词汇表
- 阔步向前冲,拥抱云计算-【软件和信息服务】2012.10
- Mongodb数据库连接
- 前端教程丨手把手教你用 Next.js 搭建个人博客,从入门到吃鸡
- AppSettings和ConnectionStrings的区别
- linux下统计文件的数目,Linux下如何统计文件数目
- java 基础做增删改查教学_Java Mybatis 增删改查 简单使用 入门 简版
- UVa 1605 (构造) Building for UN
- Exchange 2013 、Lync 2013、SharePoint 2013
- Linux查看系统glibc版本号
- linux安装php-redis扩展(转)
- .NET程序员修炼之道
- Status: Checked in and viewable by authorized users 出现在sharepoint 2013 home 页面
- opencv 物体尺寸测量
- PL330 DMAC笔记(2) - DMAC接口,状态机,初始化,APB slave接口
- 上网本丢失F盘怎么恢复
- 保险行业防范网络犯罪新思路
- PDN仿真笔记5-电容走线影响寄生电感的因素分析
热门文章
- 龙猫服务器注册,龙猫数据BPO,为企业打造安全专业的标注外包服务
- win7计算机打开一直在搜索,在win7电脑中打开文件夹却变成了搜索界面怎么办?...
- 数据挖掘——如何利用Python实现产品关联性分析apriori算法篇
- 手机wifi延迟测试软件,如何测试无线投屏延时值?同屏延时怎么测? 四画面延时多少?同屏延时 传屏器延时 电脑投屏...
- 计算机房设备搬迁协议,机房设备搬迁服务合同.doc
- c代码实现 ifft运算_C语言系列之FFT算法实现
- IDEA 官网本地无法访问
- OpenCV学习笔记(八)--颜色空间及转换
- 快应用官方IDE使用说明
- python有趣小程序春节祝福-python3:春节自动回复祝福(微信)