当前位置: 首页 > news >正文

StampedLock详解

在现代的Java应用中,同步是一个核心问题,尤其是在高并发环境下。Java提供了多种同步机制,从基本的synchronized关键字到更高级的ReentrantLock。但在Java 8中,引入了一个新的同步原语——StampedLock,它旨在提供更高的性能,特别是在读操作远多于写操作的场景中。

1.什么是StampedLock?

StampedLock是一个同步工具,它支持三种访问模式:写锁、乐观读和悲观读。这三种模式使得StampedLock能够在不同的使用场景下提供更高的吞吐量。
StampedLock 是 Java 8 引入的一种新的同步原语,用于替代 ReentrantLock 以提供更高的并发性能。它使用了一种称为 “乐观读”(optimistic reading)的技术,以及 “写锁”(write lock)和 “读锁”(read lock)的分离,以优化读多写少的场景。

2.特点

  1. 三种访问模式
  • 写锁:独占锁,用于修改数据。
  • 乐观读:不阻塞其他读或写,但在数据实际被读取前,会检查锁是否已被其他线程获取。
  • 悲观读:阻塞写但不阻塞其他读。
  1. 优化读操作:在大量读操作和较少写操作的场景中,StampedLock 可以提供更好的性能。
  2. 不可重入:与 ReentrantLock 不同,StampedLock 不是可重入的。
  3. 无条件公平性StampedLock 不提供任何公平性保证。

3.构造函数和相关方法

  1. 实例化
StampedLock lock = new StampedLock();
  1. 写锁
long stamp = lock.writeLock();
try {// 修改共享数据的代码
} finally {lock.unlockWrite(stamp);
}
  1. 乐观读
long stamp = lock.tryOptimisticRead();
// 读取共享数据的代码
if (!lock.validate(stamp)) {// 如果在读取过程中锁被其他线程获取,则执行以下代码stamp = lock.readLock();try {// 重新读取共享数据的代码} finally {lock.unlockRead(stamp);}
}
  1. 悲观读
long stamp = lock.readLock();
try {// 读取共享数据的代码
} finally {lock.unlockRead(stamp);
}

注意事项

  • 由于 StampedLock 不可重入,因此在同一个线程中多次获取同一个锁时,必须小心。
  • StampedLock 没有与 Condition 类似的机制,因此不适合需要等待/通知模式的场景。
  • 在使用乐观读时,需要注意 validate() 方法的调用,以确保在读取过程中锁没有被其他线程获取。

4.为什么选择StampedLock?

与传统的ReentrantLock相比,StampedLock在以下方面提供了优势:

  • 性能StampedLock通过乐观读和悲观读的分离,优化了读多写少的场景。在大量读操作的场景下,StampedLock可以提供比ReentrantLock更高的吞吐量。
  • 灵活性:开发者可以根据具体的使用场景选择合适的锁模式。例如,在数据更新不频繁,但读取非常频繁的场景下,乐观读可能是一个更好的选择。

5.使用示例

首先是Counter类,它使用StampedLock来保护其内部计数器:

import java.util.concurrent.locks.StampedLock;public class Counter {private int count;private final StampedLock lock = new StampedLock();public void increment() {long stamp = lock.writeLock();try {count++;} finally {lock.unlockWrite(stamp);}}public int read() {long stamp = lock.readLock();try {return count;} finally {lock.unlockRead(stamp);}}public int optimisticRead() {long stamp = lock.tryOptimisticRead();int currentCount = count;// 检查在读取过程中是否有写操作if (!lock.validate(stamp)) {// 如果写锁已被获取,则升级为悲观读锁stamp = lock.readLock();try {currentCount = count;} finally {lock.unlockRead(stamp);}}return currentCount;}
}

接下来是测试类CounterTest,它将创建多个线程来模拟并发读写操作:

public class CounterTest {public static void main(String[] args) throws InterruptedException {final Counter counter = new Counter();// 创建并启动写线程Thread writer = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});// 创建并启动读线程Thread reader = new Thread(() -> {int sum = 0;for (int i = 0; i < 1000; i++) {sum += counter.read();}System.out.println("Sum read via pessimistic lock: " + sum);});// 创建并启动乐观读线程Thread optimisticReader = new Thread(() -> {int optimisticSum = 0;for (int i = 0; i < 1000; i++) {optimisticSum += counter.optimisticRead();}System.out.println("Sum read via optimistic lock: " + optimisticSum);});// 启动所有线程writer.start();reader.start();optimisticReader.start();// 等待所有线程完成writer.join();reader.join();optimisticReader.join();// 打印最终计数器的值System.out.println("Final counter value: " + counter.read());}
}

运行结果:

Sum read via pessimistic lock: 999000
Sum read via optimistic lock: 990000
Final counter value: 1000

在这个例子中,pessimistic lock(悲观锁)指的是使用readLock方法获取的读锁,它保证在读取计数器时不会被写线程中断。而optimistic lock(乐观锁)则尝试在不阻塞的情况下读取计数器,但如果在读取过程中发生了写操作,则会重新读取。

由于乐观读不保证每次都能成功,所以在高并发环境下,乐观读计算的和可能会小于实际写入的次数。然而,在读多写少且写冲突不频繁的场景下,乐观读通常能够提供更高的吞吐量。

6.总结

StampedLock是一个强大的同步工具,它在特定的使用场景下可以提供比传统锁更高的性能。

相关文章:

StampedLock详解

在现代的Java应用中&#xff0c;同步是一个核心问题&#xff0c;尤其是在高并发环境下。Java提供了多种同步机制&#xff0c;从基本的synchronized关键字到更高级的ReentrantLock。但在Java 8中&#xff0c;引入了一个新的同步原语——StampedLock&#xff0c;它旨在提供更高的…...

Linux中DCHP与时间同步

目录 一、DHCP &#xff08;一&#xff09;工作原理 1.获取 2.续约 &#xff08;二&#xff09;分配方式 &#xff08;三&#xff09;服务器配置 1.随机地址分配 2.固定地址分配 二、时间同步 &#xff08;一&#xff09;ntpdate &#xff08;二&#xff09;chrony …...

国产系统-银河麒麟桌面版V10安装字体-wps安装字体

安装系统:银河麒麟V10 demodemo-pc:~/桌面$ cat /proc/version Linux version 5.10.0-8-generic (builddfa379600e539) (gcc (Ubuntu 9.4.0-1kylin1~20.04.1) 9.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #33~v10pro-KYLINOS SMP Wed Mar 22 07:21:49 UTC 20230.系统缺失…...

python 10常用自动化脚本收藏好

01、 图片优化器 使用这个很棒的自动化脚本&#xff0c;可以帮助把图像处理的更好&#xff0c;你可以像在 Photoshop 中一样编辑它们。 该脚本使用流行的是 Pillow 模块 # Image Optimizing # pip install Pillow import PIL # Croping im PIL.Image.open("Image1.jp…...

java物品检验管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web 物品检验管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…...

Pandas实战100例 | 案例 2: 数据探索 - 查看和理解数据

案例 2: 数据探索 - 查看和理解数据 知识点讲解 在数据分析的早期阶段&#xff0c;对数据进行初步的探索是非常重要的。这包括查看数据的基本信息、统计摘要、以及数据的形状。 示例代码 查看数据的基本信息 # 显示 DataFrame 的基本信息&#xff0c;包括列名、非空值数量…...

c++qt-基本组件

1. Designer 设计师&#xff08;掌握&#xff09; Qt包含了一个Designer程序&#xff0c;用于通过可视化界面设计开发界面&#xff0c;保存的文件格式为.ui&#xff08;界面文件&#xff09;。界面文件内部使用xml语法的标签式语言。 在Qt Creator中创建项目时&#xff0c;选中…...

SpringBoot多环境配置Maven Profile组

Maven profile组 注意切换配置时 mvn clean下 或者 clean 加install 或者compile 编译 clean之后 install下 或者compile 编译 nohup java -Xms256m -Xmx512m -Dfile.encodingUTF-8 -jar demo.jar --spring.profiles.activeprod > system.log 2>&1 &...

服务器配置 ssh 密钥登录

服务器配置 ssh 密钥登录 配置 服务器安全组策略&#xff0c;开放 ssh 22 端口&#xff0c;以 root 用户登录服务器。 配置 ssh key 登录 ssh-keygen 生成公钥和私钥对 如果不需要其他设置&#xff0c;一直回车 可以在 ~/.ssh 目录下看到两个文件&#xff0c;即刚生成的私钥…...

使用递归将list转换成tree

在产品研发时遇到这样一个问题&#xff0c;对于省市区县这类三级联动的数据&#xff0c;前端插件需要一次把数据全部返回&#xff0c;单纯的使用接口查询字节的没办法满足要求。 如果一次把数据全部返回&#xff0c;前端使用起来很麻烦需要一条一条的进行查找。 常规的使用方…...

untiy使用http下载资源

文章目录 提醒下载一个资源并保存到本地下载一张图片 提醒 部分API需要将Unity的 Edit/PrejectSetting/Player/OtherSetttings/AConfiguration/ApiCompatibilityLevel 设为.NetFramework 才可以使用 下载一个资源并保存到本地 private IEnumerator DownloadFormServer_IE(st…...

03-编码篇-x264编译与介绍

使用FFMPEG作编码操作时&#xff0c;会涉及到将yuv数据编码成h264数据&#xff0c;FFmpeg的libavcodec中的libx264.c会调用x264库的源码作编码&#xff1a; 1.x264库编译 下载X264&#xff0c;地址为&#xff1a;http://www.videolan.org/developers/x264.html&#xff0c;并解…...

生活自来水厂污水处理设备需要哪些

生活自来水厂是确保我们日常用水质量安全的重要设施。在自来水的生产过程中&#xff0c;污水处理设备是不可或缺的环节。那么&#xff0c;生活自来水厂的污水处理设备都有哪些呢&#xff1f;本文将为您详细介绍。 首先&#xff0c;生活自来水厂的污水处理设备主要包括预处理设备…...

Full names for abbreviations of Linux Commands

synopsis Towards/On Full names for abbreviations of Linux Commands I) website addressII) Mapping between full names and abbreviations I) website address II) Mapping between full names and abbreviations su&#xff1a;Swith user 切换用户&#xff0c;切换到ro…...

kafka下载安装部署

Apache kafka 是一个分布式的基于push-subscribe的消息系统&#xff0c;它具备快速、可扩展、可持久化的特点。它现在是Apache旗下的一个开源系统&#xff0c;作为hadoop生态系统的一部分&#xff0c;被各种商业公司广泛应用。它的最大的特性就是可以实时的处理大量数据以满足各…...

python包管理工具:pipenv的基本使用

很多语言都提供了环境隔离的支持&#xff0c;例如nodejs的node_module&#xff0c;golang的go mod&#xff0c;python也有virtualenv和pyvenv等机制。 为了建立依赖快照&#xff0c;通常会用pip freeze > requirements.txt 命令生成一个requirements.txt文件&#xff0c;在…...

AI系统ChatGPT网站系统源码AI绘画详细搭建部署教程,支持GPT语音对话+DALL-E3文生图+GPT-4多模态模型识图理解

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…...

MC-4/11/03/400步进电机驱动器的主要驱动方式有哪些?

MC-4/11/03/400步进电机驱动器的主要驱动方式有哪些&#xff1f; 步进电机驱动器是一种将电脉冲转化为角位移的执行机构。当步进驱动器接收到一个脉冲信号&#xff0c;它就驱动步进电机按设定的方向转动一个固定的角度&#xff0c;这个固定的角度被称为“步距角”。步进电机不能…...

大数据技术原理与应用期末复习(林子雨)

大数据技术原理与应用期末复习&#xff08;林子雨&#xff09; Hadoop的特性HBase编程实践NoSQL的四大类型键值数据库优点&#xff1a;缺点&#xff1a; 列族数据库优点&#xff1a;缺点&#xff1a; 文档数据库优点&#xff1a;缺点&#xff1a; 图数据库优点&#xff1a;缺点…...

C练习——魔术师猜三位数

题目&#xff1a; 有一种室内互动游戏&#xff0c;魔术师要每位观众心里想一个三位数abc&#xff08;a、b、c分别是百位、十位和个位数字&#xff09;&#xff0c;然后魔术师让观众心中记下acb、bac、bca、cab、cba五个数以及这5个数的和值。只要观众说出这个和是多少&#xf…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...