轻松并发,玩转StampedLock——Java 新一代读写锁

java——StampedLock邮戳锁 StampedLock,也称为邮戳锁或戳记锁,是Java 8中引入的一种新的锁机制,旨在优化读多写少场景下的并发性能。 阅读详情

前言

  在并发编程中,读写锁是一种常用的技术来保证数据的安全性和高效性。Java 中的 ReadWriteLock 可以让多个线程同时读取共享资源而不会出现竞争,只有在写操作时才需要独占资源。但是,如果我们想要在读操作时也可以同时写入,就需要使用 Java 8 引入的新的读写锁:StampedLock。

  StampedLock 改进了 ReadWriteLock 的缺陷,允许在读的过程中获取写锁并写入数据。由于数据可能在读的同时被写入,因此在使用 StampedLock 时需要额外的代码来判断读操作期间是否有写入操作,以确保数据的一致性。

  下面我们来介绍一下如何使用 StampedLock 来实现优秀的并发读写操作。

StampedLock 的基本用法

  StampedLock 的使用与 ReadWriteLock 类似,同样包含读锁和写锁两种模式。通过 lock() 和 unlock() 方法来获取和释放锁对象。但是,与 ReadWriteLock 不同的是,StampedLock 提供了乐观读的机制,即无需获取读锁或写锁,直接读取共享变量的值并返回一个 stamp(戳记),然后进行验证以确保数据是否被其他线程修改过,如果没有,则可以不用获取锁直接使用共享变量的值。

  下面是一个简单的示例代码,演示了如何使用 StampedLock 来控制对计数器 count 的读写访问:

public class Counter {
    private int count;
    private final StampedLock lock = new StampedLock();

    public int getCount() {
        long stamp = lock.tryOptimisticRead();
        int c = count;
        if (!lock.validate(stamp)) {
            stamp = lock.readLock();
            try {
                c = count;
            } finally {
                lock.unlockRead(stamp);
            }
        }
        return c;
    }

    public void increment() {
        long stamp = lock.writeLock();
        try {
            count++;
        } finally {
            lock.unlockWrite(stamp);
        }
    }
}

  在这个例子中,我们定义了一个 Counter 类来记录计数器 count 的值。使用 StampedLock 对象 lock 来控制对计数器 count 的访问。而 getCount() 方法中,我们首先尝试通过 lock.tryOptimisticRead() 方法获取乐观读锁,并尝试读取 count 的值。之后,我们使用 lock.validate(stamp) 方法来验证在当前操作期间是否有其他线程修改了 count 的值。如果没有修改,则可以直接返回 count 的值;如果有修改,则需要使用 lock.readLock() 方法获取读锁,并重新读取 count 的值,最后使用 lock.unlockRead(stamp) 释放读锁。

  在 increment() 方法中,我们使用 lock.writeLock() 方法获取写锁,并将 count 的值加 1。最后,通过 lock.unlockWrite(stamp) 方法释放写锁。

StampedLock 的优势

  StampedLock 相较于 ReadWriteLock 的优势在于,它提供了乐观读的机制,可以节省获取锁的开销,并且可以将读操作和写操作进行并发执行,从而大幅度提升程序的性能。但是,StampedLock 也需要通过额外的代码来保证数据的一致性,这对于开发者来说是一种挑战。

  除此之外,StampedLock 还有以下几个优势:

  • 使用StampedLock 可以减少锁的竞争,因此可以提高程序的并发性能。
  • StampedLock 支持可重入锁和非可重入锁,让开发者根据具体场景选择不同类型的锁。
  • StampedLock 支持读写模式下的非常灵活的锁定形式,读写锁和悲观/乐观读锁的组合可以满足各种复杂场景需求。

总结

  StampedLock 是 Java 8 引入的新一代读写锁,相较于 ReadWriteLock 更加灵活高效。使用 StampedLock 可以提高程序的并发性能,但需要注意数据的一致性,并且在使用时需要增加代码量。开发者可以根据具体的场景选择不同类型的锁来实现更好的并发控制。

(四)并发工具类ReadWriteLock(读写锁)与StampedLock(读写锁优化) ReadWriteLock(读写锁)与StampedLock(读写锁优化)ReadWriteLock读写锁降级StampedLock乐观读 ReadWriteLock 针对读多写少这种并发场景,Java SDK 并发包提供了读写锁——ReadWriteLock,其目的在于分场景优化性能,提升易用性。 读写锁都遵守以下三条基本原则: 允许多个线程同时读共享变量; 只允许一个线程写共享变量; 如果一个写线程正在执行写操作,此时禁止读线程读共享变量。 读写锁类似于 ReentrantLock,也支持公平模式和 阅读详情

相关推荐

Java之JUC

文章目录前置要求线程基础知识复习Futrue和Callable接口从之前的FutureTask说对Future的改进案例精讲-从电商网站的比价需求说CompletableFutrue常用方法CompletableFutrue说说Java"锁"事LockSupport与线程中断Java内存模型值JMMvolatile与Java内存模型 前置要求 线程基础知识复习 Futrue和Callable接口 从之前的FutureTask说 对Future的改进 案例精讲-从电商网站的比价需求说 CompletableF

lyw4631的博客 1220

介绍java中的StampedLock类,并学习怎么使用StampedLock类

在上面的示例代码中,我们使用了writeLock和readLock获取写锁和悲观读锁,使用tryOptimisticRead获取乐观读锁,使用tryWriteLock获取试图获取锁的写锁。如果使用乐观读锁,需要在该锁保护的共享数据上调用validate方法,检查在乐观读锁获取后,该数据是否被其他线程修改过。另外,在使用乐观读锁时,需要注意在validate方法之前,不能有其他线程修改该锁保护的共享数据,否则会导致validate方法返回false,从而触发重新获取悲观读锁的操作。

LJH_java10086的博客 389

StampedLock vs 读写锁:Java并发界的‘锁战’谁赢了?3招秒杀传统锁!

🔥关注墨瑾轩,带你探索编程的奥秘!🚀🔥超萌技术攻略,轻松晋级编程高手🚀🔥技术宝库已备好,就等你来挖掘🚀🔥订阅墨瑾轩,智趣学习不孤单🚀🔥即刻启航,编程之旅更有趣🚀。

java专栏 552

Java 锁系列(六)——StampedLock使用

一、StampedLock概述 StampedLock 是读写锁的实现,对比 ReentrantReadWriteLock 主要不同是该锁不允许重入,多了乐观读的功能,使用上会更加复杂一些,但是具有更好的性能表现。StampedLock 的状态由版本和模式组成。 获取锁方法返回一个标记,表示和控制与锁状态相关的访问; 这些方法的“尝试”版本可能会返回特殊值 0 来表示获取锁失败。 锁释放和转换方法需要标记作为参数,如果它们与锁的状态不匹配则失败。本文描述 StampedLock 的基础使用场景,入门教程。

玖涯博客 3561

Java StampedLock为什么会导致CPU100%?

🔥关注墨瑾轩,带你探索编程的奥秘!🚀🔥超萌技术攻略,轻松晋级编程高手🚀🔥技术宝库已备好,就等你来挖掘🚀🔥订阅墨瑾轩,智趣学习不孤单🚀🔥即刻启航,编程之旅更有趣🚀在Java并发编程的奇妙世界里,就像是一位双面间谍,一方面提供了读写锁的灵活性,另一方面稍有不慎就可能让你的应用程序陷入性能泥潭,CPU占用率直线上升到100%的壮观场面。想象一下,如果你的程序变成了一个永动机,不停地在原地踏步,那画面是不是既让人头疼又有点搞笑?🤔🏃‍♂️。

java专栏 1261

基于分段锁的 Harness 高并发配置读写

分段锁的核心思想资源分割:将共享资源(例如配置存储Map)分成多个独立的、互不干扰的“段(Segment)”;锁分散:为每个段分配一把独立的锁(通常是读写锁),不同段的锁互不干扰;无冲突并发:如果两个线程访问的是不同段的资源,它们可以并发进行,不需要竞争同一把锁;冲突局部化:如果两个线程访问的是同一段的资源,它们只需要竞争该段的锁,不会影响其他段的并发访问。

AI开发架构师 395

StampedLock详解

是JUC并发包里面 JDK8 版本新增的一个锁,是读写锁的一种具体实现,和不同的是其不提供可重入性,不基于某个类似Lock或者ReadWriteLock接口实现,而是基于CLH锁思想实现这点这AQS有些类似,并且StampedLock不支持条件变量Condition。关于可以参考上篇文章 ReentrantReadWriteLock详解。那么JDK既然实现了这个锁,就说明这个锁一定有优势,那就是性能优势,下面会具体分析。

落日的博客 2803

Modelsim安装教程以及管理员身份运行patch_dll.bat时找不到文件mgls.dll的解决

Modesim安装教程 Modesim版本有很多,但是安装方式大都相同,我们以modesim.10.5为例,电脑使用的是win10 64位,讲一下安装过程中的步骤以及出现问题的解决方法 一 安装 1.首先解压安装包,在解压的安装包内选择应用程序,右键选择管理员运行。 2.稍等一会,有的电脑会弹出是否允许modesim进行更改,选择 是 即可,然后出现下面的界面,点击下一步。 3.弹出此界面选择安装路径,选择安装路径,我是在D盘新建的文件夹,直接把文件夹中的路径复制在框内。文件夹名称切记不要带中文 4.

weixin_48564372的博客 1万+

并发:读写锁ReentrantReadWriteLock和StampedLock

1. 读写锁 读写锁通常遵守以下三条规则: 多个线程可以同时读共享变量; 只允许一个线程写共享变量; 对共享变量写的时候,不允许对该变量读。 简单来说,读写锁允许同时读,读和写互斥,写和写互斥。 因此,在读多写少的场景下,读写锁比普通的互斥锁更具优势。 2. 读写锁ReentrantReadWriteLock ReentrantReadWriteLock从字面上来看,可以知道它是一个可重入的读写锁。 在使用容器时,使用ReentrantReadWriteLock,可以实现较好的并发性能,尤其是在读多写少

Longstar_L的博客 545

cs231n作业 assignment 1 q1 q2 q3

请先看课程作业地址。有两种做作业的方法,一种是在google Colab上做 (需魔法),另一种就是下载到本地,但是我懒得在本地配置环境,太麻烦了,还得修改一些基础代码,我就直接在google colab上做了google colab 配置环境只需要跟着教程走就好了最后还有一题解答题懒得做的,这个题目做的没啥意思。让我们用简单写法来实现softmax的loss函数与梯度计算。

Leezed525的博客 9277

ZYNQ专题-7020驱动KSZ9031 PHY芯片

之所以有这篇文章,得益于Alinx的开发板。

Anitawen的博客 4961

StampedLock----提供“读写分离”,提高并发情况下的数据读取性能

import java.util.concurrent.locks.StampedLock; /** * @desc StampedLock使用案例 * * 补充: 使用 StampedLock 锁不需要额外创建出不同类型的 Lock 就可以很轻松地 * 完成“读写锁”的分离,提高并发情况下的数据读取性能。 **/ public class StampedLockExample { //共享数据 private static int shareData = ...

crazy的博客 282

ADC选型实战:从参数指标到精准应用的工程指南

本文深入解析ADC(模数转换器)选型的关键参数与实战技巧,涵盖分辨率、转换误差等核心指标,并提供高精度温度测量、高速数据采集等五大应用场景的选型指南。通过实际案例和代码示例,详细讲解校准方法、功耗优化策略及常见问题排查,帮助工程师实现从参数指标到精准应用的工程实践。

weixin_29166013的博客 324

Java并发编程之ReentrantLock原理及AQS原理讲解

概述 Lock 在 J.U.C 中是最核心的组件,,锁最重要的特性就是解决并发安全问题。 为什么要以 Lock 作为切入点呢?如果看过 J.U.C 包中的所有组件,一定会发现绝大部分的组件都有用到了 Lock。 所以通过 Lock 作为切入点使得在后续的学习过程中会更加轻松。 在 Lock 接口出现之前, Java 中的应用程序对于多线程的并发安全处理只能基于synchronized 关键字来解决。但是 synchronized 在有些场景中会存在一些短板,也就是它并不适合于所有的并发场景。 但是在 Jav

qq_40837310的博客 2684

瑞萨单片机,把CS文件转换为CC

1、打开CC的软件: 点击坐上角的"START" 点击"Create New Project"的"GO": 导入工程: 如下图设置后,点击"Create" 2、进入到CC的开发界面: 可以看到原启动库文件以asm文件的方式直接出现在工程中: 删除新生成的main.c,保留导入的r_main.c(以你自己的代码为准): 注意添加所有的头文件路径: 点击"...

weixin_37611121的博客 1227

使用VS Code创建第一个Flutter工程

你可以使用任意文本编辑器结合命令行工具来开发Flutter应用。然而,我们推荐使用本文介绍的编辑器插件以获取更好的开发体验。这些插件提供了代码补全、代码高亮、widget辅助编辑等功能,以及为项目的运行和调试提供支持。推荐的开发工具有VS Code、Android Studio、IntelliJ。本文将重点介绍如何使用VS Code进行Flutter应用开发。

2501_91373349的博客 2126

关于Java中同步锁的代替

使用这些机制和API可以在不少场合替代传统的锁,以实现更高效和可伸缩的并发控制。选择哪种机制取决于具体的应用场景和性能要求。在实际开发中,建议结合程序的具体需求和性能测试结果,选择最适合的并发控制机制。以下是一些举例:(1)使用AtomicInteger进行原子操作// 原子地增加计数器的值// 获取当前计数器的值(2)使用ConcurrentHashMap进行并发映射操作(3)使用进行读写分离try {try {

qq_64179563的博客 2294

2026 年 3 月青少年软编等考 C/C++ 三级测试题解析

摘要 本文包含三部分内容: 单选题(10题):考察C++基础语法和数据结构知识,涉及vector、栈、队列的操作和特性。 判断题(10题):测试对动态数组、栈、队列、字符串操作的理解,包括内存管理、访问方式和函数返回值等。 编程题(1题):模拟火车站售票窗口排队场景,要求根据输入输出各窗口的排队情况,重点考查队列的实际应用和边界条件处理。 答案解析详细,涵盖常见编程考点,适合检验基础知识的掌握程度。

发布少儿编程考级的真题和优秀竞赛题解析,以及一些讲义。 248

并发编程(四)AQS的底层原理分析

J.U.C 简介 Java.util.concurrent 是在并发编程中比较常用的工具类,里面包含很多用来在并发场景中使用的组件。比如线程池、阻塞队列、计时器、同步器、并发集合等等。并发包的作者是大名鼎鼎的 Doug Lea。我们在接下来的课程中,回去剖析一些经典的比较常用的组件的设计思想 Lock Lock 在 J.U.C 中是最核心的组件,前面我们讲 synchronized 的时候说过,锁最重要的特性就是解决并发安全问题。为什么要以 Lock 作为切入点呢?如果有同学看过 J.U.C 包中的所有组件

leon 3276

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

多线程高并发场景下为什么需要锁

如果线程A执行完了x=x+1的操作,但还没有来得及将修改后的值写入内存中,此时线程B先执行了x=x-1的操作,那么最终x的值就是原始值,而不是应该的值。4.StampedLock:StampedLock是Java中提供的一种乐观锁,它采用了乐观锁和悲观锁相结合的方式实现同步,可以在保证线程安全的同时提高程序的并发性。虽然锁会引入一定的开销,但是在多线程高并发的情况下,使用锁可以避免线程之间的竞争,从而提高程序的性能和效率。在Java语言中,提供了多种类型的锁,每种锁都有其特定的应用场景和使用方式。

qq_41194023的博客 2790

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

AQS原理分析

JUC简介 ​ Java.util.concurrent 是在并发编程中比较常用的工具类,里面包含很多用来在并发场景中使用的组件。比如线程池、阻塞队列、计时器、同步器、并发集合等等。并发包的作者是大名鼎鼎的 Doug Lea。我们在接下来会去剖析一些经典的比较常用的组件的设计思想 Lock ​ Lock 在 J.U.C 中是最核心的组件,前面我们讲 synchronized 的时候说过,锁最重要的...

黄金时代的架构之路 493

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

嗯!这篇多线程不错!伍

开篇闲扯 前面几篇写了有关Java对象的内存布局、Java的内存模型、多线程锁的分类、Synchronized、Volatile、以及并发场景下出现问题的三大罪魁祸首。看起来写了五篇文章,实际上也仅仅是写了个皮毛,用来应付应付部分公司“八股文”式的面试还行,但是在真正的在实际开发中会遇到各种稀奇古怪的问题。这时候就要通过线上的一些监测手段,获取系统的运行日志进行分析后再对症下药,比如JDK的jstack、jmap、命令行工具vmstat、JMeter等等,一定要在合理的分析基础上优化,否则可能就是系统小“感

罗拉快跑跑跑的博客 173

Java岗:十余年实战经验积累,进大厂必备:三位阿里P8大牛精心整理的笔记《并发编程核心讲义》

这主要是硬件的驱动以及国内互联网行业的飞速发展决定的,现在 64 核的服务器已经飞入寻常百姓家,大型互联网厂商的系统并发量轻松过百万,传统的中间件和数据库已经不能为我们遮风挡雨,反而成了瓶颈所在。于是,并发编程成为近年非常热门的领域,人才稀缺。但与此同时,关于并发编程的书籍也渐渐丰富起来了,庞杂而且生涩难懂。经过这些年接触,我发现很多小伙伴,都是工作几年后很多技术突飞猛进,只有并发编程成为瓶颈,并发相关的类库他们也熟悉,却总是写不出正确、高效的并发程序,原因在哪里?

weixin_66896902的博客 606

ReentrantLock底层原理分析

在Lock接口出现之前,Java中的应用程序对于多线程的并发安全处理只能基于关键字来解决。但是在有些场景中会存在一些短板,也就是它并不适合于所有的并发场景。但是在Java5以后,Lock的出现可以解决在某些场景中的短板,它比更加灵活。Lock。

m0_71777195的博客 225

阿里P7私传“并发编程核心讲义”,实战案例剖析,个个都是经典

最近几年,并发编程已经慢慢成为了一项必备技能。高薪岗位面试必问,并发编程似乎已经成为大厂必备的敲门砖。 这主要是硬件的驱动以及国内互联网行业的飞速发展决定的,现在 64 核的服务器已经飞入寻常百姓家,大型互联网厂商的系统并发量轻松过百万,传统的中间件和数据库已经不能为我们遮风挡雨,反而成了瓶颈所在。 于是,并发编程成为近年非常热门的领域,人才稀缺。但与此同时,关于并发编程的书籍也渐渐丰富起来了,庞...

玩赚AI大模型的博客 330
上一篇: 读写分离,快如闪电——Java中ReadWriteLock的应用解析
下一篇: Java中的原子类:从解剖到应用
JavaWizard-M
博客等级 码龄6年 3159粉丝 148原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值