多线程(31)StampedLock和ReadWriteLock

2024-04-06 01:52

本文主要是介绍多线程(31)StampedLock和ReadWriteLock,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

StampedLock 是 Java 8 引入的一种新的锁机制,位于 java.util.concurrent.locks 包下。它可以被认为是 ReadWriteLock 的一个改进版,提供了一种乐观的读锁策略,这种策略可以在某些场景下减少锁的竞争,从而提高性能。与 ReadWriteLock 相比,StampedLock 在使用时需要更加注意,因为它的锁方法不支持重入,并且不支持条件变量。

工作原理

StampedLock 提供了三种主要的访问模式:

  1. 写锁(Write Lock)

    • 类似于 ReadWriteLock 的写锁,提供了排他性的访问。
    • 获取写锁时,StampedLock 会阻塞读锁和写锁的获取。
  2. 悲观读锁(Pessimistic Read Lock)

    • 类似于 ReadWriteLock 的读锁,但在 StampedLock 中被称为悲观读锁。
    • 当获取到悲观读锁时,写锁的请求会被阻塞,直到所有悲观读锁都释放。
  3. 乐观读(Optimistic Read)

    • 这是 StampedLock 独有的一种读取模式。
    • 乐观读不会阻塞写锁的获取,也不会获取实际的锁;它会返回一个邮戳(stamp),代表这次读的版本。
    • 在数据实际读取之前,需要检查邮戳,看看在读取过程中有没有写操作进行,如果有,乐观读需要退化为悲观读锁或者重新读取数据。

锁的获取和释放

每次锁的获取操作,无论是读锁还是写锁,StampedLock 都会返回一个表示锁状态的邮戳(stamp)。这个邮戳在锁的释放时必须要提供,作为释放锁的凭证。这是一个与 ReadWriteLock 显著不同的特点,因为 ReadWriteLock 并不需要这样的邮戳。

重要特点

  • 非阻塞的乐观读
    StampedLock 支持一种非阻塞的读取锁,这可以减少线程阻塞,提高系统吞吐量。

  • 不支持条件变量
    StampedLock 不支持条件变量。如果需要类似条件变量的特性,需要使用 ReentrantLock 或者 ReadWriteLock

  • 不支持重入
    StampedLock 的锁不支持重入。如果一个线程已经持有锁,它不能再次获取锁,否则可能会导致死锁。

  • 中断敏感性
    StampedLock 的锁获取方法提供中断敏感和非中断敏感的版本,这意味着获取锁的操作可以响应中断。

  • 锁的转换
    StampedLock 允许从读锁转换为写锁,反之亦然,通过使用特定的方法来尝试转换锁,并检查返回的邮戳是否有效。

示例代码

下面展示了一个使用 StampedLock 的简单示例,包括悲观读锁和写锁的使用:

import java.util.concurrent.locks.StampedLock;public class StampedLockExample {private final StampedLock sl = new StampedLock();// 模拟共享资源private int sharedState;public void write(int newValue) {long stamp = sl.writeLock(); // 获取写锁,并返回邮戳try {sharedState = newValue;} finally {sl.unlockWrite(stamp); // 释放写锁,并提供邮戳}}public int read() {long stamp = sl.readLock(); // 获取悲观读锁,并返回邮戳try {return sharedState;} finally {sl.unlockRead(stamp); // 释放读锁,并提供邮戳}}public int optimisticRead() {long stamp = sl.tryOptimisticRead(); // 尝试获取乐观读,并返回邮戳int currentState = sharedState; // 读取共享资源if (!sl.validate(stamp)) { // 检查在读取过程中是否有写操作stamp = sl.readLock(); // 退化为悲观读锁try {currentState = sharedState;} finally {sl.unlockRead(stamp);}}return currentState;}
}

在这个示例中,我们展示了如何在 StampedLock 中获取和释放写锁和悲观读锁,以及如何执行乐观读取并验证它是否仍然有效。注意:在实际使用中,你需要小心地管理锁的释放,以避免死锁和资源泄露。

这篇关于多线程(31)StampedLock和ReadWriteLock的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/878716

相关文章

多线程解析报表

假如有这样一个需求,当我们需要解析一个Excel里多个sheet的数据时,可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完之后,程序需要提示解析完成。 Way1 join import java.time.LocalTime;public class Main {public static void main(String[] args) thro

Java 多线程概述

多线程技术概述   1.线程与进程 进程:内存中运行的应用程序,每个进程都拥有一个独立的内存空间。线程:是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换、并发执行,一个进程最少有一个线程,线程实际数是在进程基础之上的进一步划分,一个进程启动之后,进程之中的若干执行路径又可以划分成若干个线程 2.线程的调度 分时调度:所有线程轮流使用CPU的使用权,平均分配时间抢占式调度

Java 多线程的基本方式

Java 多线程的基本方式 基础实现两种方式: 通过实现Callable 接口方式(可得到返回值):

JAVA- 多线程

一,多线程的概念 1.并行与并发 并行:多个任务在同一时刻在cpu 上同时执行并发:多个任务在同一时刻在cpu 上交替执行 2.进程与线程 进程:就是操作系统中正在运行的一个应用程序。所以进程也就是“正在进行的程序”。(Windows系统中,我们可以在任务管理器中看 到进程) 线程:是程序运行的基本执行单元。当操作系统执行一个程序时, 会在系统中建立一个进程,该进程必须至少建立一个线

多线程篇(阻塞队列- LinkedBlockingDeque)(持续更新迭代)

目录 一、LinkedBlockingDeque是什么 二、核心属性详解 三、核心方法详解 addFirst(E e) offerFirst(E e) putFirst(E e) removeFirst() pollFirst() takeFirst() 其他 四、总结 一、LinkedBlockingDeque是什么 首先queue是一种数据结构,一个集合中

Linux 删除 当前下的 mysql-8.0.31 空文件夹

在Linux中,如果你想要删除当前目录下的名为mysql-8.0.31的空文件夹(即该文件夹内没有任何文件或子文件夹),你可以使用rmdir命令。但是,如果mysql-8.0.31文件夹并非完全为空(即它包含文件或子文件夹),rmdir命令会失败。 如果你的目标是删除mysql-8.0.31文件夹及其内部的所有内容(无论是否为空),你应该使用rm命令结合-r(或-R,它们是等价的)选项来递归地删

多线程篇(阻塞队列- LinkedBlockingQueue)(持续更新迭代)

目录 一、基本概要 1. 构造函数 2. 内部成员 二、非阻塞式添加元素:add、offer方法原理 offer的实现 enqueue入队操作 signalNotEmpty唤醒 删除线程(如消费者线程) 为什么要判断if (c == 0)时才去唤醒消费线程呢? 三、阻塞式添加元素:put 方法原理 图解:put线程的阻塞过程 四、非阻塞式移除:poll方法原理 dequ

spring笔记 多线程的支持

spring的工作机制 136  属性编辑器 140 spring事件的体系结构 168 Bean间的关系 109 继承 依赖 引用     Bean的继承          1 为了简化初始化的属性注入;          2 子Bean和父Bean相同的属性值,使用子Bean的     Bean的依赖 Srping控制相互依赖的Bean之间,属性注入的顺序,防止出错  depend-on

【编程底层思考】详解Java的JUC多线程并发编程底层组件AQS的作用及原理

Java中的AbstractQueuedSynchronizer(简称AQS)是位于java.util.concurrent.locks包中的一个核心组件,用于构建锁和其他同步器。AQS为实现依赖于FIFO(先进先出)等待队列的阻塞锁和相关同步器提供了一套高效、可扩展的框架。 一、AQS的作用 统一同步状态管理:AQS提供了一个int类型的成员变量state,用于表示同步状态。子类可以根据自己

多线程的系列文章

Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1)   Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多线程学习(四)等待/通知(wait/notify)机制 Java多线程学习(五)线程间通信知识点补充 Java多线程学习(六)Lock锁的使用 Java多