详解java中的ReentrantReadWriteLock

读写锁ReentrantReadWriteLock详解 读写锁、ReentrantReadWriteLock 阅读详情

Java中的ReentrantReadWriteLock是java.util.concurrent.locks包下实现读写分离的高效锁机制,适用于读多写少的并发场景。它通过区分读锁(共享锁)和写锁(独占锁),在保证线程安全的同时提升系统吞吐量。以下从核心特性、实现原理、使用方式及注意事项四方面详细解析:

一、核心特性

  1. 读写分离机制

    • 读锁(Shared):允许多个线程同时获取读锁,适用于只读操作(如查询)。
    • 写锁(Exclusive):仅允许一个线程获取写锁,适用于写操作(如修改)。写锁持有期间,其他线程(无论读或写)均被阻塞。
  2. 可重入性
    同一线程可重复获取同一类型的锁(读锁或写锁),避免死锁。例如:

    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    lock.writeLock().lock(); // 获取写锁
    lock.writeLock().lock(); // 可重入,不会阻塞
  3. 锁降级(Downgrade)
    线程可先获取写锁,再获取读锁,最后释放写锁。此时其他线程可获取读锁,但无法获取写锁。例如:

    lock.writeLock().lock();        // 获取写锁
    lock.readLock().lock();         // 降级为读锁(写锁未释放)
    lock.writeLock().unlock();      // 释放写锁(读锁仍持有)
  4. 公平性与非公平性
    支持公平模式(按请求顺序分配锁)和非公平模式(默认,写线程可能插队)。公平模式需显式构造:

    ReentrantReadWriteLock fairLock = new ReentrantReadWriteLock(true);

二、实现原理

基于AQS(AbstractQueuedSynchronizer)实现,内部维护两个锁:

  • 读锁:通过共享模式(sharedCount)管理,多个线程可同时持有。
  • 写锁:通过独占模式(exclusiveCount)管理,仅允许一个线程持有。

关键状态管理:

  • 使用一个int类型变量(如state)的高16位存储读锁持有数,低16位存储写锁重入次数。
  • 写锁获取时,需检查读锁是否被其他线程持有(避免写锁饥饿);读锁获取时,需确保无写锁或当前线程持有写锁。

三、使用方式

  1. 基本API

    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    Lock readLock = lock.readLock();    // 获取读锁
    Lock writeLock = lock.writeLock();  // 获取写锁
    
    // 读操作示例
    readLock.lock();
    try {
        // 执行只读操作
    } finally {
        readLock.unlock();
    }
    
    // 写操作示例
    writeLock.lock();
    try {
        // 执行写操作
    } finally {
        writeLock.unlock();
    }
  2. 锁降级示例

    writeLock.lock();         // 获取写锁
    try {
        // 修改数据
        readLock.lock();      // 降级为读锁(写锁未释放)
    } finally {
        writeLock.unlock();   // 释放写锁(读锁仍持有)
    }

四、注意事项

  1. 避免写锁饥饿
    非公平模式下,写线程可能因读线程持续获取锁而饥饿。可通过公平模式或限制读锁持有时间缓解。

  2. 锁释放必须配对
    每次lock()必须对应一次unlock(),通常在try-finally块中释放,防止死锁。

  3. 锁降级规则

    • 仅支持“写锁→读锁”的降级,不支持“读锁→写锁”的升级。
    • 写锁降级后,其他线程可获取读锁,但无法获取写锁。
  4. 性能权衡
    在“读多写少”场景下性能提升显著;若写操作频繁,可能因锁竞争导致性能下降(此时考虑StampedLock或synchronized)。

  5. 中断支持
    lockInterruptibly()方法允许线程在阻塞时响应中断,需配合tryLock()使用。

五、适用场景

  • 缓存系统(如Redis客户端、本地缓存)
  • 配置中心(频繁读取、少修改)
  • 数据库连接池(读操作多,写操作少)
  • 资源访问统计(如计数器、状态监控)

总结:ReentrantReadWriteLock通过读写分离和可重入特性,在并发场景中平衡了安全性与性能。使用时需根据业务特点(读/写比例、锁持有时间)选择公平模式或非公平模式,并注意锁的获取/释放配对及降级规则,避免死锁和性能损耗。在Java 8之后,也可结合StampedLock进一步优化性能(如乐观读)。

通俗易懂读写锁ReentrantReadWriteLock的使用 ReentrantReadWriteLock不知道大家熟悉吗?其实在实际的项目中用的比较少,反正我所在的项目没有用到过。ReentrantReadWriteLock称为读写锁,它提供一个读锁,支持多个线程共享同一把锁。它也提供了一把写锁,是独占锁,和其他读锁或者写锁互斥,表明只有一个线程能持有锁资源。通过两把锁的协同工作,能够最大化的提高读写的性能,特别是读多写少的场景,而往往大部分的场景都是读多写少的。本文主要讲解ReentrantReadWriteLock的使用和应用场景。 阅读详情

相关推荐

基于R语言 meta/metafor 包进行荟萃分析(一)

在此部分中,使用连续结果详细描述了通用逆方差方法及其在meta分析中的应用,还介绍了固定效应法和随机效应法。我们已经展示了如何分别将典型数据与metacont和metagen函数一起使用,以及如何print和绘制森林图。我们还讨论了估计研究间方差的各种方法,并将Hartung-Knapp平差描述为经典随机效应方法的替代方法。此外,我们还说明了byvar选项的使用,这使得亚组分析更加简单。关于亚组分析的更多细节见后续章节。

Dunaichuanyi的博客 1万+

ReentrantReadWriteLock读写锁

一、前言 ReentrantReadWriteLock中包含三种锁:读写锁、可重入锁、公平/非公平锁 1、读写锁 2、可重入锁: 又名递归锁,是指在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。说的有点抽象,下面会有一个代码的示例。 对于Java ReetrantLock而言,从名字就可以看出是一个重入锁,其名字是Re entrant Lock 重新进入锁。 对于Synchronized而言,也是一个可重入锁。可重入锁的一个好处是可一定程度避免死锁。 syn...

m0_56054652的博客 4360

TL431过压保护电路实战:5.5V阈值设计全流程(附MOSFET选型建议)

本文详细介绍了基于TL431和MOSFET构建5.5V阈值过压保护电路的完整设计流程。内容涵盖核心原理、阈值计算、驱动电路设计,并重点针对大电流应用场景,提供了MOSFET选型与散热处理的实战建议,帮助工程师打造可靠高效的电源保护方案。

weixin_28327051的博客 536

并发编程之ReentrantReadWriteLock详解

ReentrantReadWriteLock是Java中的一个读写锁实现,它允许多个线程同时读取共享资源(读读可以并发),但在写入时只允许一个线程独占(读写,写读,写写互斥)。这个锁支持重入,即同一个线程可以多次获取相同类型的锁。这种锁可以提高读操作的并发性,同时保证写操作的独占性。在读多于写的情况下,读写锁能够提供比排它锁更好的并发性和吞吐量。线程进入读锁的前提条件没有其他线程的写锁没有写请求或者有写请求,但调用线程和持有锁的线程是同一个。

尽力而为! 1943

第三方系统(异构系统)基于token身份认证方式访问Ecology9的Restful接口Ecology9服务器配置部分

通过Token的认证方式调用Ecology9系统Restful业务接口服务器配置部分

svsou的专栏 2175

CAD文件转换避坑指南:Inventor导出STP时这些设置千万别忽略

本文深入解析了使用Autodesk Inventor导出STP文件时的关键设置与避坑指南。重点探讨了应用协议选择、样条曲线拟合精度对几何保真度的影响,以及装配体结构和元数据的保全策略,旨在帮助用户实现高质量、零误差的CAD数据交付,避免下游软件打开时出现特征丢失或曲面破碎等问题。

weixin_29214559的博客 518

ReentrantReadWriteLock原理详解

当读操作远远高于写操作时,这时候使用读写锁让读——读可以并发,提高性能。 类似于数据库中的select.,from..lockinsharemode 提供一个数据容器类内部分别使用读锁保护数据的read()方法,写锁保护数据的write()方法 简单来说,就是读锁可以共享,但是写锁必须独占 一、ReentrantReadWriteLock JUC为我们提供了一个可用于读和写的读写锁。 简单看下使用方法: ReentrantReadWriteLo...

m0_53127809的博客 3469

杰理AC695N/AC696N/AC701N系列芯片在线调音教程

本教程详细介绍AC695N/AC696N/AC701N芯片在线音效调试方法,包括工具准备(需安装杰理包管理器)、程序修改(需关闭USB功能并启用在线调试宏)、连接方式(USB或串口)、音效调节步骤(EQ和混响参数调整)以及配置保存。注意事项包括版本匹配、连接检查和供电稳定等,并提供常见问题解决方案。适用于快速配置实时音效调试环境并保存最终配置。

qq_42014563的博客 1406

【Java第82集】java ReentrantReadWriteLock类详解

是 Java 并发编程中非常强大的工具,尤其适合读多写少的场景。通过区分读锁和写锁,它能够在保证线程安全的同时显著提高并发性能。合理选择锁类型:读操作使用读锁,写操作使用写锁。锁降级的正确使用:确保数据可见性,避免死锁。注意锁的公平性:根据实际需求选择非公平或公平模式。避免锁升级:锁升级可能导致死锁,应严格遵循锁降级的规则。

学不可以已,活到老,学到老。 1199

10、使用Ray Serve实现微服务与模型部署

本文深入介绍了如何使用Ray Serve实现微服务与机器学习模型的高效部署。从基础的部署定义到复杂的模型服务场景,涵盖部署架构、HTTP与Python调用、资源配置、FastAPI集成、金丝雀发布策略及实际应用流程。文章还探讨了模型服务的关键需求如灵活性、批处理、硬件优化和可扩展性,并展示了Ray Serve如何满足这些要求。最后提供了常见问题解决方案与未来发展方向,帮助开发者构建高性能、易维护的模型服务平台。

blue42的博客 175

Java读写锁ReentrantReadWriteLock原理详解

ReentrantLock属于排他锁,这些锁在同一时刻只允许一个线程进行访问,而读写锁ReentrantReadWriterLock在同一时刻可以允许多个线程访问,但是在写线程访问时,所有的读和其他写线程都被阻塞。读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。下面我们来看看读写锁ReentrantReadWriter特性公平性选择:支持非公平(默认)和公平的锁获取模式,非公平的吞吐量优于公平;重入性。

潘建南的博客 3560

CADENCE 25.1打开元件库ERRORCannot perform the operation because of an exception.

摘要:解决CADENCE25.1打开元件库报错"ERRORCannotperformtheoperationbecauseofanexception"的方法:该错误通常由软件中文设置导致。解决方案为:进入Options→Preferences→MorePreferences,取消勾选两个本地语言选项后重启软件即可恢复正常。此方法简单有效,能快速解决因语言设置导致的元件库访问异常问题。(98字)

0 1017

【Java并发编程】读写锁ReentrantReadWriteLock详解

本文详细介绍了 Java 中 ReentrantReadWriteLock 读写锁的实现原理和使用方法。 重要亮点:状态变量 state及通过对state进行位运算操作同时维护读锁和写锁、写锁和读锁的获取和释放原理、锁降级

叉烧钵钵鸡的博客 1006

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

java并发编程 ReentrantReadWriteLock详解

基于AQS的能力,实现了尝试加锁和尝试释放锁的方法。把state的高16位作为state使用,还是利用原子自增自减的方式去保证原子性。读锁使用的AQS里的shard方法。ReentrantReadWriteLock把锁的粒度划分成读锁和写锁,读锁和读锁不互斥,减小了锁粒度。在实现方面,完全基于AQS实现。相关文章已在上面列出。

weixin_46082526的博客 606

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Java中的读写锁ReentrantReadWriteLock详解,存在一个小缺陷

读锁是共享锁,写锁是独占锁。在过去学习的过程中我们学过 synchronized、 ReentrantLock这种独占式锁,他们的好处是保证了线程的安全,缺点是同一时刻只能有一个线程持有锁,大大的影响了效率,而之前学过的Semaphore(信号量)这种呢,虽然支持同一时刻被多个线程获取,但它不能很好的保障线程安全性,我们需要的是一种效率高、安全性好的同步锁。,因为在写的时候,是独占模式,其他线程不能读也不能写,这时候若有大量的读操作的话,那这些线程也只能等待着,从而带来写饥饿。那么这个读写锁如何使用呢?

JavaBuild的博客 834

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Java多线程读写锁ReentrantReadWriteLock原理详解

ReentrantLock属于排他锁,这些锁在同一时刻只允许一个线程进行访问,而读写锁在同一时刻可以允许多个线程访问,但是在写线程访问时,所有的读和其他写线程都被阻塞。读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。 下面我们来看看读写锁ReentrantReadWriter特性 公平性选择:支持非公平(默认)和公平的锁获取模式,吞吐量还是非公

路漫漫,水迢迢 1万+

Java多线程 - ReentrantReadWriteLock读写锁详解

1.读写锁简介 现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源;但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写的操作了。 针对这种场景,JAVA的并发包提供了读写锁ReentrantReadWriteLock,它表示两个锁,一个是读操作相关的锁...

qiang_zi_的专栏 340

Java并发编程之ReentrantReadWriteLock详解

ReentrantLock是排他锁,排他锁在同一时刻仅有一个线程可以进行访问,实际上独占锁是一种相对比较保守的锁策略,在这种情况下任何“读/读”、“读/写”、“写/写”操作都不能同时发生,这在一定程度上降低了吞吐量。然而读操作之间不存在数据竞争问题,如果"读/读"操作能够以共享锁的方式进行,那会进一步提升性能。因此引入了ReentrantReadWriteLock,顾名思义,ReentrantRe...

zhutianrong520的博客 205

【Java多线程】ReentrantReadWriteLock详解

1.定义ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有writer,读取锁可以由多个reader 线程同时保持。写入锁是独占的。2.适用性 ReadWriteLock 读取操作通常不会改变共享资源,但执行写入操作时,必须独占方式来获取锁。对于读取操作占多数的数据结构。ReadWriteLock 能提供比独占锁更高的并发性。而对于只读的数据结构,其中包含

白夜行 507

Java 中的Lock锁对象(ReentrantLock/ReentrantReadWriteLock)详解

当有线程获取读锁时,如果当前没有线程持有写锁,则读锁将立即被获取,读锁计数器加一,表示当前有一个线程持有读锁。在 getValue() 方法中,线程会获取锁,返回共享变量 value 的值,最后释放锁。例如,如果一个线程在尝试获取锁的过程中遇到了饥饿现象(即一直获取不到锁),那么系统可能会采用类似于睡眠的方式,让该线程暂时让出 CPU 资源,等待一段时间后再次尝试获取锁。接着,它获取读锁,释放写锁,这样就实现了锁降级。这是因为写锁是独占锁,不能被多个线程同时持有,而读锁是共享锁,可以被多个线程同时持有。

swadian2008的博客 4023

java readandwrite_Java并发之ReentrantReadWriteLock设计实现详解

概述维护了一对关联的锁,一个用于只读操作,另一个用于写操作。其中写锁是独占的,只要没有写操作,多个读线程可以同时持有读锁。也就是说,成功获取读锁的线程将看到在先前的写锁上所做的所有更新。1、不频繁写,频繁读,适合使用读写锁。否则,大部分时间会被写锁独占。2、如果读操作过于短,则读写锁的实现会占用绝大部分性能开销,因为比一般的互斥锁执行逻辑更复杂。变量含义理解下面的变量含义,有助于理解代码。Stat...

weixin_36364707的博客 190

java读写锁锁变量_ReentrantReadWriteLock读写锁详解

一、读写锁简介现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源;但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写的操作了。针对这种场景,JAVA的并发包提供了读写锁ReentrantReadWriteLock,它表示两个锁,一个是读操作相关的锁,称为共享...

weixin_39647499的博客 331

【Java 并发编程】读写锁 ReentrantReadWriteLock & StampLock 详解

读写锁 ReadWriteLock,顾名思义一把锁分为读与写两部分,读锁允许多个线程同时获得,因为读操作本身是线程安全的。而写锁是互斥锁,不允许多个线程同时获得写锁。并且读与写操作也是互斥的。读写锁适合多读少写的业务场景。针对读多写少场景,Java 的并发包提供了读写锁 ReentrantReadWriteLock,整体架构和实现都与 ​​ReentrantLock​​​ 类似,不同之处在于​​ ReentrantReadWriteLock ​​​分为读锁和写锁,读锁是共享锁,可多个读线程共享一把锁;

迪曼奥特迦-博客 1301
上一篇: Java泛型详解:从入门到精通
Jack_abu
博客等级 码龄10年 633粉丝 78原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack_abu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值