`

【Java核心-进阶】读写锁 ReentrantReadWriteLock vs StampedLock

    博客分类:
  • Java
 
阅读更多



 


ReadWriteLock

ReadWriteLock 表示一对锁,分别对应操作;所以需要给它一个单独的接口。

ReentrantReadWriteLock “再入”语义与 ReentrantLock 类似。

  • 在实际使用场景中,有时候以并发读取为主
    • 读操作不会改变数据,所以读操作之间不需要互斥
  • 对以上场景,ReentrantLock 和 synchronized 的“要么不占,要么独占”的方式过于粗犷
  • 为了优化性能,需要粒度更细的锁

当试图获取读锁时,如果写锁已被其它线程持有,那么只能等待写锁所在线程先结束,这样就能保证不会读到脏数据

 

public class ReadWriteLockUser {
    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final Lock readLock = readWriteLock.readLock();
    private final Lock writeLock = readWriteLock.writeLock();

    public Object read() {
        readLock.lock();
        try {
            return readData();
        } finally {
            readLock.unlock();
        }
    }

    public void write() {
        writeLock.lock();
        try {
            writeData();
        } finally {
            writeLock.unlock();
        }
    }
}

 

 

 

StampedLock

为了进一步优化读操作的性能,基于假设“大部分读操作不会和写操作冲突”,引入 StampedLock。

 

读操作的基本步骤

  1. 通过 tryOptimisticRead() 方法获取 StampedLock 当前的戳
  2. 读取数据
  3. 验证第1步中获得的戳和当前 StampedLock 的戳是否一致。如果一致,则表示此次读操作未被写操作污染,直接返回读到的数据;否则进入第4步
  4. 获取读锁
  5. 读取数据
  6. 释放读锁
  7. 返回读到的数据

写操作的基本步骤

  1. 获取写锁
  2. 写数据
  3. 释放写锁

示例代码

public class StampedLockUser {
    private final StampedLock lock = new StampedLock();

    public void write() {
        // 获取写锁
        long stamp = lock.writeLock();
        try {
            // 写数据
            writeData();
        } finally {
            // 释放写锁
            lock.unlockWrite(stamp);
        }
    }

    public Object read() {
        long stamp;
        // 获取 StampedLock 当前的戳;如果 stamp 等于0,表示已被互斥锁定,没必要先读数据
        if (0 != (stamp = lock.tryOptimisticRead())) {
            // 读取数据
            Object data = readData();
        }

        // 校验 StampedLock 的戳
        if (!lock.validate(stamp)) {
            // 未通过校验
            // 获取读锁
            stamp = lock.readLock();
            try {
                // 读取数据
                data = readData();
            } finally {
                // 释放读锁
                sl.unlockRead(stamp);
            }
        }

        // 返回读到的数据
        return data;
    }
}
  • 大小: 14.4 KB
分享到:
评论

相关推荐

    08、读写锁ReentrantReadWriteLock&StampLock详解-ev

    读写锁ReentrantReadWriteLock&StampLock详解_e读写锁ReentrantReadWriteLock&StampLock详解_e读写锁ReentrantReadWriteLock&StampLock详解_e读写锁ReentrantReadWriteLock&StampLock详解_e读写锁...

    Java 多线程与并发(12-26)-JUC锁- ReentrantReadWriteLock详解.pdf

    在Java多线程并发编程中,ReentrantReadWriteLock(可重入读写锁)是一个重要的同步工具,它属于Java并发包(java.util.concurrent.locks)中的一个类。这个锁提供了比标准的synchronized关键字更细粒度的控制,允许...

    8、读写锁ReentrantReadWriteLock&StampLock详解.pdf

    根据提供的文件信息,本文将详细解析读写锁`ReentrantReadWriteLock`以及`StampLock`在Java并发编程中的应用场景及其实现原理。 ### 一、读写锁介绍 #### 1.1 读写锁的基本概念 读写锁是一种特殊的锁机制,它可以...

    计算机软件-商业源码-利用读写锁保持线程同步.zip

    读写锁的概念源于操作系统理论,但在许多编程语言中都有实现,如Java的`java.util.concurrent.locks.ReentrantReadWriteLock`和C++的`std::shared_timed_mutex`。下面将详细探讨读写锁的工作原理、优缺点以及如何在...

    java 读写锁代码

    在Java的`java.util.concurrent.locks`包中,`ReentrantReadWriteLock`类实现了读写锁的功能。这个锁允许多个读取者同时访问资源,但在有写入者时,所有读取者和写入者都会被阻塞,以确保数据的一致性。下面我们将...

    Java的两种读写锁介绍

    本文将深入探讨Java中的两种读写锁:ReentrantReadWriteLock和StampedLock,并分析它们的工作原理、特点以及如何在实际开发中进行应用。 一、ReentrantReadWriteLock(可重入读写锁) 1. **简介**: ...

    笔记16-JAVAEE之多线程进阶

    Java 多线程进阶 - 锁策略与读写锁 在 Java 多线程编程中,锁策略和读写锁是两个非常重要的概念。本文将对 Java 多线程进阶中的锁策略和读写锁进行详细介绍。 锁策略 在多线程编程中,锁策略是一个非常重要的概念...

    60.Lock-ReentranLock-ReentrantReadWriteLock.mp4

    在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。

    关于读写锁算法的Java实现及思考

    在Java中,`java.util.concurrent.locks`包下的`ReadWriteLock`接口提供了读写锁的抽象定义,具体实现由`ReentrantReadWriteLock`类提供。`ReentrantReadWriteLock`实现了`ReadWriteLock`接口,提供了`readLock()`和...

    java多线程-读写锁原理

    Java 5开始,`java.util.concurrent.locks`包提供了`ReentrantReadWriteLock`类来实现可重入的读写锁。 1. **读/写锁的Java实现**: `ReentrantReadWriteLock`类提供了读锁(`ReadLock`)和写锁(`WriteLock`)两...

    java进阶提高学习教程-14锁机制.pptx

    在 Java 中,锁有多种不同的实现机制,如可重入锁、读写锁、互斥锁、悲观锁、乐观锁、公平锁、锁消除、独享锁、共享锁等。 可重入锁 可重入锁,也叫做递归锁,指的是同一线程外层函数获得锁之后,内层递归函数仍然...

    JAVA技术栈-锁机制知多少

    2. **Lock接口**:包括ReentrantLock、ReentrantReadWriteLock、StampedLock等,提供了更细粒度的控制,如可指定公平/非公平,以及尝试获取锁、释放锁、中断等待等功能。其中,ReentrantLock是可重入的,而...

    Java并发编程进阶练习代码

    Java提供了多种锁机制,包括内置锁(synchronized)、显式锁(java.util.concurrent.locks包下的Lock接口及其实现)以及读写锁(ReentrantReadWriteLock)。理解并熟练使用这些锁能帮助你控制线程的执行顺序,解决竞...

    行业分类-设备装置-双模式读写锁.zip

    在Java中,`java.util.concurrent.locks.ReentrantReadWriteLock`类提供了可重入的读写锁实现。而在C++中,标准库中的`std::shared_mutex`和`std::unique_lock`可以用来实现读写锁。这些库提供了灵活的接口,允许...

    Java 读写锁实现原理浅析

    本文主要介绍了 Java 读写锁实现原理浅析,包括读写锁的定义、读写锁的实现原理、ReentrantReadWriteLock 的实现机制等。 读写锁的定义 读写锁是一种机制,允许多个线程安全地访问共享资源。读写锁分为读锁和写锁...

    读写锁_读写锁_

    在Java中,`java.util.concurrent.locks.ReentrantReadWriteLock`是标准的读写锁实现。这个类提供了可重入的特性,意味着一个线程在获得读锁或写锁后,可以再次请求相同的锁而不会被阻塞。这在处理递归调用时特别...

    Java互联网架构多线程并发编程原理及实战 视频教程 下载.zip

    4-8 读写锁特性及ReentrantReadWriteLock的使用.mp4 4-9 源码探秘之AQS如何用单一int值表示读写两种状态.mp4 4-10 深入剖析ReentrantReadWriteLock之读锁源码实现.mp4 4-11 深入剖析ReentrantReadWriteLock之写锁...

    Java互联网架构多线程并发编程原理及实战 视频教程 下载4.zip

    4-8 读写锁特性及ReentrantReadWriteLock的使用.mp4 4-9 源码探秘之AQS如何用单一int值表示读写两种状态.mp4 4-10 深入剖析ReentrantReadWriteLock之读锁源码实现.mp4 4-11 深入剖析ReentrantReadWriteLock之写锁...

    Java互联网架构多线程并发编程原理及实战 视频教程 下载2.zip

    4-8 读写锁特性及ReentrantReadWriteLock的使用.mp4 4-9 源码探秘之AQS如何用单一int值表示读写两种状态.mp4 4-10 深入剖析ReentrantReadWriteLock之读锁源码实现.mp4 4-11 深入剖析ReentrantReadWriteLock之写锁...

    Java互联网架构多线程并发编程原理及实战 视频教程 下载3.zip

    4-8 读写锁特性及ReentrantReadWriteLock的使用.mp4 4-9 源码探秘之AQS如何用单一int值表示读写两种状态.mp4 4-10 深入剖析ReentrantReadWriteLock之读锁源码实现.mp4 4-11 深入剖析ReentrantReadWriteLock之写锁...

Global site tag (gtag.js) - Google Analytics