文章目录

  • 1. 简介
  • 2. 代码示例

1. 简介

StampedLock(印戳锁)是对ReentrantReadWriteLock读写锁的一种改进,主要的改进为:在没有写只有读的场景下,StampedLock支持不用加读锁而是直接进行读操作,最大程度提升读的效率,只有在发生过写操作之后,再加读锁才能进行读操作

StampedLock有以下3种模式:

  1. 悲观读锁:与ReadWriteLock的读锁类似(这里的读锁不可重入),多个线程可以同时获取悲观读锁,悲观读锁是一个共享锁。
  2. 乐观读锁:相当于直接操作数据,不加任何锁,连读锁都不要。在操作数据前并没有通过CAS 设置锁的状态,仅仅通过位运算测试。如果当前没有线程持有写锁 ,则简单地返回 一个非 0 的 stamp 版本信息 ,返回0则说明有线程持有写锁。 获取该 stamp 后在具体操作数据前还需要调用validate 方法验证该 s tamp 是否己经不可用
  3. 写锁:与ReadWriteLock的写锁类似,写锁和悲观读锁是互斥的。虽然写锁与乐观读锁不会互斥,但是在数据被更新之后,之前通过乐观读锁获得的数据已经变成了脏数据。是 一 个排它锁或者独占锁,某时只有 一 个线程可以获取该锁,当二个线程获取该锁后,其他请求读锁和写锁的线程必须 等待 ,这类似于ReentrantReadWriteLock 的写锁(不同点在于这里的写锁不可重入)

StampedLock 的读写锁都是不可重入锁,所以在获取锁后释放锁前不应该再调用会获取锁的操作,以避免造成调用线程被阻塞


2. 代码示例

package innerlock;import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.locks.StampedLock;public class StampedLockTest {//创建1个map 代表共享数据final static HashMap<String, String> MAP=new HashMap<>();//创建一个印戳锁final static StampedLock STAMPED_LOCK=new StampedLock();/** 对共享数据的写操作*/public static Object put(String key,String value) {long stamp=STAMPED_LOCK.writeLock();try {System.out.println(getNowTime()+": 抢占了写锁,开始写操作");String put=MAP.put(key, value);return put;} catch (Exception e) {e.printStackTrace();}finally {System.out.println(getNowTime()+": 释放了写锁");STAMPED_LOCK.unlock(stamp);}return null;}/** 对共享数据的悲观读操作*/public static Object pessimisticRead(String key) {System.out.println(getNowTime()+":  进入过写模式,只能悲观读");long stamp=STAMPED_LOCK.readLock();try {System.out.println(getNowTime()+": 获取了读锁");String value=MAP.get(key);return value;} finally {System.out.println(getNowTime()+": 释放了读锁");STAMPED_LOCK.unlockRead(stamp);}}/** 对共享数据的乐观读操作*/public static Object optimisticRead(String key) {String value=null;long stamp=STAMPED_LOCK.tryOptimisticRead();if(stamp!=0) {System.out.println(getNowTime()+":  乐观锁的印戳值获取成功");value=MAP.get(key);}else if (stamp==0) { //代码1System.out.println(getNowTime()+":  乐观锁的印戳值获取失败,开始使用悲观读");return pessimisticRead(key);}if(!STAMPED_LOCK.validate(stamp)) {//代码2处System.out.println(getNowTime()+":  乐观读的印戳值已经过期");return pessimisticRead(key);}else {System.out.println(getNowTime()+":  乐观读的印戳值没有过期");return value;}}public static Date getNowTime() {return new Date();}public static void main(String[] args) throws InterruptedException {MAP.put("initKey", "initValue");Thread t1=new Thread(()->{System.out.println(optimisticRead("initKey"));},"读线程1");Thread t2=new Thread(()->{put("key1", "value1");},"写线程1");Thread t3=new Thread(()->{System.out.println(optimisticRead("initKey"));},"读线程2");t1.start();t1.join();t2.start();t3.start();Thread.sleep(1000);}}
  • 代码1处stamp==0说明当前为写锁模式,只能使用悲观读
  • 代码2处: 乐观读已经过了一段时间,期间可能发生写入,所以验证乐观读的印戳值是否有效,即判断LOCK是否进入过写模式

StampedLock(印戳锁)详解相关推荐

  1. 多线程锁详解之【临界区】

    更多的锁介绍可以先看看这篇文章:多线程锁详解之[序章] 正文: 一般锁的类型可分为两种:用户态锁和内核态锁.用户态锁是指这个锁的不能够跨进程使用.而内核态锁就是指能够跨进程使用的锁.一般书中会说,wi ...

  2. mysql默认使用悲观锁_mysql乐观锁和悲观锁详解

    mysql乐观锁和悲观锁详解 相信很多朋友在面试的时候,都会被问到乐观锁和悲观锁的问题,如果不清楚其概念和用法的情况下,相信很多朋友都会感觉很懵逼,那么面试的结果也就不言而喻了. 那么乐观锁和悲观锁到 ...

  3. 可重入锁详解(什么是可重入)

    可重入锁详解 概述 什么是 "可重入",可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁.例如 package com.test.reen;// 演示可重入锁是什么 ...

  4. 公平锁非公平锁的实际使用_java 线程公平锁与非公平锁详解及实例代码

    java 线程公平锁与非公平锁详解 在ReentrantLock中很明显可以看到其中同步包括两种,分别是公平的FairSync和非公平的NonfairSync.公平锁的作用就是严格按照线程启动的顺序来 ...

  5. python gil 解除_详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案

    先看一道GIL面试题: 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. GIL:又叫全局解 ...

  6. Redis分布式锁详解

    Redis分布式锁详解 1. 分布式所概述 1.1 分布式锁 2. 缓存数据库Redis 2.1 redis简介 2.2 Springboot整合Redis两种方式 3. 实现验证 3.1 环境准备 ...

  7. Redis缓存雪崩、穿透、击穿,布隆过滤器,分布式锁详解

    缓存雪崩 在某一个时间存在大量的缓存key失效 解决办法 1.有效期一直---->给每一个数据加上水机有效期 2.redis挂掉了----->使用redis集群,分摊key的存储 引出re ...

  8. 旋转矩阵、欧拉角、万向锁详解

    旋转矩阵.欧拉角.万向锁详解 一:物体的姿态描述 物体的姿态可由固定于此物体的坐标系描述,为了规定空间某刚体B的姿态,设置一直角坐标系{B}与此刚体固接.用坐标系{B}的三个单位主矢量{Xb,Yb,Z ...

  9. Java锁详解:“独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁+线程锁”

    在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 线程锁 乐观锁 VS 悲 ...

  10. 最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁

    在Java并发场景中,会涉及到各种各样的锁,比如:高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景,这些锁有对应的种类:公平锁,乐观锁,悲观锁等等,这篇文章来详细介绍各种锁的分类: 公 ...

最新文章

  1. 各计算机语言之父,四大编程语言之父
  2. Caffe2——cifar10数据集创建lmdb或leveldb类型的数据
  3. 天气预报开放API调用
  4. java第二阶段_Java第二阶段总结
  5. Linux下jdk配置环境变量
  6. MYSQL-创建存储过程
  7. Computer Vision News
  8. 关于阿里云OSS报错-java.lang.ClassNotFoundException: org.jdom.input.JDOMParseException
  9. list集合排序_Java面试第七部分 Java的集合
  10. matplotlib绘图基础
  11. 重置winsock目录
  12. matlab画图常用函数image、imagesc、imshow区别
  13. 创业者2012必看十大文章(10)
  14. 2021年全球与中国颅骨稳定系统行业市场规模及发展前景分析
  15. 取消键盘Fn功能键方式
  16. Go Module使用 六大场景讲解示例
  17. ENSP的AR40问题解决
  18. 3.7版本逆向微信实现多开
  19. 渗透测试学习计划路线思维导图v1.0
  20. 4.怎么理解相互独立事件?真的是没有任何关系的事件吗? 《zobol的考研概率论教程》

热门文章

  1. 图解迷宫算法(广度优先遍历)
  2. excel能和html链接吗,excel中怎么设置超链接并且整个excel表格发给别人时超链接还是能用...
  3. 经纬度坐标转换xy坐标 python_Python 高斯坐标转经纬度算法
  4. 计算机操作入门基础知识,电脑入门基本操作知识
  5. android packagemanager源码,Android源码个个击破之PackageManager
  6. getParameterValues使用
  7. 电脑写作与发布哪款软件好?
  8. mysql的pdb文件在哪里_pdb是什么文件?pdb数据库文件怎么打开?
  9. 机械工程c语言第一学期考试题,科学出版社机械工程图学习题集1~10章答案.ppt
  10. windows server2008 安装iscsi服务