java.util.concurrent.locks.ReentrantReadWriteLock 读写锁

2023-11-05

读写锁简介:

对共享资源有读和写的操作,且写操作没有读操作那么频繁。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源;但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写的操作了。

针对这种场景,JAVA的并发包提供了读写锁ReentrantReadWriteLock,它表示两个锁,一个是读操作相关的锁,称为共享锁;一个是写相关的锁,称为排他锁,描述如下:

线程进入读锁的前提条件:

没有其他线程的写锁,

没有写请求或者有写请求,但调用线程和持有锁的线程是同一个。

线程进入写锁的前提条件:

没有其他线程的读锁

没有其他线程的写锁

而读写锁有以下三个重要的特性:

(1)公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。

(2)重进入:读锁和写锁都支持线程重进入。

(3)锁降级:遵循获取写锁、获取读锁再释放写锁的次序,写锁能够降级成为读锁。

实现效果:
在这里插入图片描述
代码实现:

import java.util.concurrent.locks.ReentrantReadWriteLock;

/*
 * @author 在下令狐
 * @date 2020/10/27
 */
public class ReentrantReadWriteLockTest {

    //读写锁对象
    private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    //获得读锁
    private ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
    //获得写锁
    private ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();

    //执行read方法时,需要获取读锁,而此时其他线程均可访问该方法而不被阻塞。
    //可以说这是一个类似于concurrentHashMap的原型,但它的效率肯定没有concurrentHashMap高,但比HashTable要强一些 。
    public void read() {
        readLock.lock();
        try {
            System.out.println("线程 " + Thread.currentThread().getName() + " 进入了读方法。。。");
            Thread.sleep(3000);
            System.out.println("线程 " + Thread.currentThread().getName() + " 退出了读方法。。。");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readLock.unlock();
        }
    }

    //执行write方法时,必须提前获取写锁,当获取写锁之后,其他线程对于读锁和写锁的获取均被阻塞,只有写锁释放后,其他读操作才能继续。
    public void write() {
        writeLock.lock();
        try {
            System.out.println("线程 " + Thread.currentThread().getName() + " 进入了写方法。。。");
            Thread.sleep(3000);
            System.out.println("线程 " + Thread.currentThread().getName() + " 退出了写方法。。。");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
        }
    }

    public static void main(String[] args) {
        ReentrantReadWriteLockTest lockTest = new ReentrantReadWriteLockTest();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                lockTest.read();
            }
        }, "t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                lockTest.read();
            }
        }, "t2");

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                lockTest.write();
            }
        }, "t3");

        Thread t4 = new Thread(new Runnable() {
            @Override
            public void run() {
                lockTest.write();
            }
        }, "t4");

        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java.util.concurrent.locks.ReentrantReadWriteLock 读写锁 的相关文章

  • Java:获取当前正在执行的Method对应的对象

    将当前正在执行的方法作为 Method 对象获取的最优雅的方法是什么 我的第一个明显的方法是在辅助类中使用静态方法 该方法将加载当前线程堆栈 获取正确的堆栈跟踪元素 并根据其信息构造 Method 元素 有没有更优雅的方法来实现这一目标 这
  • 如何使用 Java 将 HTML 内容转换为 PDF 而不丢失格式?

    我有一些 HTML 内容 包括格式化标签 例如strong 图像等 在我的 Java 代码中 我想将此 HTML 内容转换为 PDF 文档 而不丢失 HTML 格式 有没有办法用 Java 来实现 使用 iText 或任何其他库 I use
  • 获取jdbc中表依赖顺序

    我在 MySQL 数据库中有一组表 A B C D 依赖关系如下 B gt C gt A 和 D gt A 也就是说 A 有一个 PrimaryKey C 有一个外键指向 A 的主键 B 有一个外键指向 C 的主键 类似地 D 有一个外键指
  • Java Sqlite Gradle

    我对 gradle 和 java 还很陌生 我有一个使用 sqlite 的项目 它通过 intellij idea 运行良好 但我无法从终端运行它 它会抛出异常 java lang ClassNotFoundException org sq
  • 从剪贴板获取图像 Awt 与 FX

    最近 我们的 Java FX 应用程序无法再从剪贴板读取图像 例如 用户在 Microsofts Paint 中选择图像的一部分并按复制 我不是在谈论复制的图像文件 它们工作得很好 我很确定它过去已经有效 但我仍然需要验证这一点 尽管如此
  • 空 EntityManager/EJB 注入 MDB

    我有一个消息驱动 bean MDB 部署到 WebLogic 12 1 3 我尝试使用 PersistenceContext 注释将实体管理器注入 MDB 但实体管理器为空 我还尝试注入一个简单的无状态会话 bean 它也是空的 但是 Me
  • JAX-WS:有状态 WS 在独立进程中失败

    我在 Tomcat 上部署了一个有状态的 Web 服务 它由工厂服务和主要 API 服务组成 并且工作得很好 工厂服务将 W3CEndpointReference 返回到主 API 实例 客户端使用会话 现在 我尝试将相同的服务作为独立应用
  • 代码编译期间遇到警告消息“使用或覆盖已弃用的 API”

    我编译了我的程序并收到以下错误 我该如何解决呢 Note ClientThreadClients java uses or overrides a deprecated API Note Recompile with Xlint depre
  • 动画图像视图

    目前我正在开发一款游戏 这是我的游戏的详细信息 用户应选择正确的图像对象 我希望图像从左到右加速 当他们到达终点时 他们应该再次出现在活动中 这是我正在处理的屏幕截图 我有 5 个图像视图 它们应该会加速 您有此类动画的示例代码吗 非常感谢
  • Codility 钉板

    尝试了解 Codility NailingPlanks 的解决方案 问题链接 https app codility com programmers lessons 14 binary search algorithm nailing pla
  • 带有面板的 Java Swing JToolbar:外观和感觉

    我有一个JToolbar其中包含多个JPanels 需要 因为我希望每个都有特定的边界 不幸的是 外观管理器无法识别JPanels属于工具栏和JButtons因此 渲染器与普通按钮一样 即没有工具栏上的特殊鼠标悬停效果 更换JPanels
  • 更改 JTextPane 的大小

    我是Java新手 刚刚在StackOverflow中找到了这段代码 ResizeTextArea https stackoverflow com questions 9370561 enabling scroll bars when jte
  • Hystrix是否可以订阅CircuitBreaker开启事件?

    对于单元测试 我希望能够订阅 Hystrix 事件 特别是在断路器打开或关闭时发生事件 我四处寻找示例 似乎解决方法是利用指标流并监视断路器标志 由于 Hystrix 是基于 RxJava 构建的 我认为应该在某个地方有一个事件订阅接口 在
  • 无法在 Mac OS X 上启动应用程序 我收到错误 LSOpenURLsWithRole() 应用程序失败,错误为 -10810

    问题 我正在尝试启动一个应用程序 遗传网络分析仪 http www genostar com category products gna 但它默默地失败了 使用时open gna app产生以下错误消息 LSOpenURLsWithRole
  • 如何使用 Spring MVC 和 Thymeleaf 添加静态文件

    我的问题是如何添加 CSS 和图像文件等静态文件 以便我可以使用它们 我正在使用 Spring MVC 和 Thymeleaf 我查看了有关此主题的各种帖子 但它们对我没有帮助 所以我才来问 根据这些帖子 我将 CSS 和图像文件放在res
  • 尝试在空对象引用上调用虚拟方法“java.lang.String org.jsoup.nodes.Element.ownText()”

    我正在使用下面的代码来获取版本名称 from 应用商店通过使用 jsoup 我正在获取详细信息 但它引发了一些异常 我的代码是 public class ForceUpdateAsync extends AsyncTask
  • 如何在 Java 中创建要打印到 JFrame 的 JLabels 数组

    我正在尝试制作一系列标签 每个标签都有一个来自函数的不同值 我不知道要使用的标签的确切数量 我的意思是可以打印任意数量的值 请帮我做这件事 很简单 只需一个方法返回一个数组或一些 JLabels 集合 并将它们全部添加到您的 JCompon
  • java中wav文件转换为字节数组

    我的项目是 阿塞拜疆语音的语音识别 我必须编写一个程序来转换wav文件到字节数组 如何将音频文件转换为byte 基本上如第一个答案中的片段所描述 但不是BufferedInputStream use AudioSystem getAudio
  • BoneCP 和 Derby - 如何正确关闭

    I have BoneCP CONNECTION POOL CONNECTION POOL getConfig setJdbcUrl jdbc derby database shutdown true Connection connecti
  • 编译时在代码中替换Java静态最终值?

    在java中 假设我有以下内容 fileA java class A public static final int SIZE 100 然后在另一个文件中我使用这个值 fileB java import A class b Object t

随机推荐

  • java poi 4.1.2 操作excel说明

    文章目录 描述 导包 excel写入 excel读取 数据类型与多行多列 描述 poi是Apache下一款java语言excle高效读写工具 本博客将从读 写等方面做说明 xls 2007前版本 和xlsx 2007版本和此后 使用不同类
  • bat:使用bat脚本获得文件名,修改时间,大小

    echo for i in D J 1012 ftprun log do echo nxi echo zi字节 echo ti echo Y gt ni log pause
  • 固高运动控制卡IO口输入输出

    固高运动控制卡开发资料 关注我免费下载 输入 板卡上的输入 long ss 0 GT GetDi MC GPI ss bool gpists 1 lt lt bit 1 bit为输入接口号 拓展模块的输入 short Extflag 0 返
  • Qt 样式表之QSS

    前言 最近想给程序做个换皮肤的功能 于是想起了用 QSS QSS 这个东西也算是老古董了 博主刚工作那会就有接触过 但是没有深入去了解 趁着这一次机会来学习一下 网上翻阅了一些资料 结合 Qt 的官方文档 博主把 QSS 的相关知识点整理了
  • [1063]CM+CDH6.3.2环境搭建(全网最全)

    文章目录 1 环境准备 1 1 三台虚拟机准备 1 2 常用yum源更新 gcc G C 等环境 可以跳过 1 3 配置本地yum云 1 3 1 更新yum源httpd 1 3 2 更新yum源yum utils 1 3 3 将下载好的资源
  • Laravel8.x + jwt 授权系统

    1 创先一个新项目 composer create project prefer dist laravel laravel my app 2 配置好数据库后迁移数据 php artisan migrate 3 让我们为 User 模型创建一
  • configParse 是如何解析配置文件的,下面解析配置文件的步骤,并用具体示例说明

    1 创建文件test ini以及存放内容 2 我的是python3 需要安装 pip install ConfigParser 3 创建ConfigParser对象 4 在上面的代码allow no value参数表示在配置文件中是否允许选
  • EFK6.3+kafka+logstash日志分析平台集群

    转载来源 EFK6 3 kafka logstash日志分析平台集群 https www jianshu com p f956ebbb2499 架构解读 第一层 数据采集层 安装filebeat做日志采集 同时把采集的日志发送给kafka
  • JS中的块级作用域

    JS中是没有块级作用域作用域这个概念 为实现块级作用域可通过闭包的形式实现 下面通过一个例子来说一下JS中的块级作用域 function outputName count for var i 0 i
  • 大数据电商数据仓库系统搭建(CDH数仓) 附离线安装包

    一 Cloudera Manager 概述 1 CM 简介 Cloudera Manager是一个拥有集群自动化安装 中心化管理 集群监控 报警功能的一个工具 使得安装集群从几天的时间缩短在几个小时内 运维人员从数十人降低到几人以内 极大的
  • Qt在Windows上简单调用opencv摄像头Demo

    OpenCV也和Qt一样 有很多版本 有各种平台版本 Android ios Windows Linux等 同样在Windows上 也分vc10 vc11 vc12版 做一个简单的demo 用Qt调用opencv摄像头接口显示当前摄像头画面
  • STM32 Keil中关于stlink的调试 下载设置

    1 首先找到魔法棒 或者右键项目 选择第一个Options of 2 找到Debug 选择stlink下载 点击setting 3 选择模式为SW模式 点击确定 进入下一步 4 点击Utilities选项卡 先取消use debug dri
  • 线性同余法生成随机数Matlab_生成安全的随机数

    0x01 生产随机数的方式 Math random 0到1之间随机数 java util Random伪随机数 线性同余法生成 java security SecureRandom真随机数 java util concurrent Thre
  • 【源码&库】在调用 createApp 时,Vue 为我们做了那些工作?

    在使用Vue3时 我们需要使用createApp来创建一个应用实例 然后使用mount方法将应用挂载到某个DOM节点上 那么在调用createApp时 Vue再背后做了些什么事情呢 今天就来扒一扒Vue3的源码 看看调用createApp发
  • android知识点总结

    1 抗锯齿 会占用系统资源 对于线条 mPaint setAntiAlias true 对于图片 canvas setDrawFilter new PaintFlagsDrawFilter 0 Paint FILTER BITMAP FLA
  • phpstudy CRMEB安装配置mysql sql-mode报错及配置redis

    安装CRMEB程序时 数据库报mysql数据库报 请在mysql配置文件修sql mode为NO AUTO CREATE USER NO ENGINE SUBSTITUTION 找了好几个答案都redi是错误的 试错半小时总结最靠谱答案如下
  • AI算法工程师

    文章目录 一 我们身处人工智能的时代 人工智能的时代 人工智能的应用 二 人工智能的流程和基本概念 人工智能常见流程 人工智能基本概念与区别 三 人工智能的常见任务和本质 有监督机器学习任务与本质 无监督机器学习任务与本质 一 我们身处人工
  • docker 卸载镜像_为什么删除docker镜像后依然占用本地空间?

    bin bash Copyright 2017 Th o Chamley Permission is hereby granted free of charge to any person obtaining a copy of this
  • linux高级程序设计

    这本阿里P8撰写的算法笔记 再次推荐给大家 身边不少朋友学完这本书最后加入大厂 Github 疯传 史上最强悍 阿里大佬 LeetCode刷题手册 开放下载了 一网络通信基础 TCP IP协议簇基础 之所以称TCP IP是一个协议簇 是因为
  • java.util.concurrent.locks.ReentrantReadWriteLock 读写锁

    读写锁简介 对共享资源有读和写的操作 且写操作没有读操作那么频繁 在没有写操作的时候 多个线程同时读一个资源没有任何问题 所以应该允许多个线程同时读取共享资源 但是如果一个线程想去写这些共享资源 就不应该允许其他线程对该资源进行读和写的操作