提升--22---ReentrantReadWriteLock读写锁

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • ReadWriteLock----读写锁
    • 1.读写锁介绍
    • 线程进入读锁的前提条件:
    • 线程进入写锁的前提条件:
    • 而读写锁有以下三个重要的特性:
  • ReentrantReadWriteLock的使用
        • 10、ReentrantReadWriteLock读写锁出现的目的?
        • 11、ReentrantReadWriteLock如何基于AQS实现的?


ReadWriteLock----读写锁

1.读写锁介绍

现实中有这样一种场景

对共享资源有读和写的操作,且写操作没有读操作那么频繁(读多写少)
在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源(读读可以并发)
但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写操作了(读写,写读,写写互斥)
在读多于写的情况下,读写锁能够提供比排它锁更好的并发性和吞吐量。

针对这种场景,JAVA的并发包提供了读写锁ReentrantReadWriteLock,它内部,维护了一对相关的锁,一个用于只读操作,称为读锁;一个用于写入操作,称为写锁

这个ReadWriteLock 是读写锁。读写锁的概念其实就是共享锁和排他锁,读锁就是共享锁,写锁就是排他锁

  • 读锁 —共享锁
  • 写锁 —排他锁

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

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

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

  • 没有其他线程的读锁
  • 没有其他线程的写锁

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

  1. 公平选择性:支持非公平(默认)和公平的锁获取方式,吞吐量还是非公平优于公平。
  2. 可重入:读锁和写锁都支持线程重入。以读写线程为例:读线程获取读锁后,能够再次获取读锁。写线程在获取写锁之后能够再次获取写锁,同时也可以获取读锁。
  3. 锁降级:遵循获取写锁、再获取读锁最后释放写锁的次序,写锁能够降级成为读锁。

ReentrantReadWriteLock的使用

  • 我们这有两个方法,read()读一个数据,write()写一个数据。read这个数据的时候我需要你往里头传一把锁,这个传那把锁你自己定,我们可以传自己定义的全都是排他锁,也可以传读写锁里面的读锁或写锁。write的时候也需要往里面传把锁,同时需要你传一个新值,在这里值里面传一个内容。我们模拟这个操作,读的是一个int类型的值,读的时候先上锁,设置一秒钟,完了之后read over,最后解锁unlock。再下面写锁,锁定后睡1000毫秒,然后把新值给value,write over后解锁,非常简单。
  • new ReentrantReadWriteLock() 是ReadWriteLock的一种实现,在这种实现里头我又分出两把锁来,一把叫readLock,一把叫writeLock,通过他的方法readWriteLock.readLock()来拿到readLock对象,读锁我就拿到了。通过readWriteLock.writeLock()拿到writeLock对象。这两把锁在我读的时候扔进去,因此,读线程是可以一起读的,也就是说这8个线程可以一秒钟完成工作结束。所以使用读写锁效率会大大的提升。
package com.cy.month12;import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class T10_TestReadWriteLock {private static int value;static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();static Lock readLock = readWriteLock.readLock();static Lock writeLock = readWriteLock.writeLock();public static void read(Lock lock) {try {lock.lock();Thread.sleep(1000);System.out.println("read over!");//模拟读取操作} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public static void write(Lock lock, int v) {try {lock.lock();Thread.sleep(1000);value = v;System.out.println("write over!");//模拟写操作} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public static void main(String[] args) {Runnable readR = ()-> read(readLock);Runnable writeR = ()->write(writeLock, new Random().nextInt());for(int i=0; i<8; i++) new Thread(readR).start();for(int i=0; i<2; i++) new Thread(writeR).start();}
}

在这里插入图片描述

10、ReentrantReadWriteLock读写锁出现的目的?

首先,读写锁能解决的,互斥锁肯定能解决,但是,互斥锁的效率可能比较低。

比如说有一个业务,平均下来,10次读操作,1次写操作。

如果用互斥锁,可以保证线程安全,但是10次读操作也需要一个一个来。

但是,读读操作没有线程安全问题。

但是只要涉及到了写操作,比如读写操作,需要保证线程安全。只要有写线程,就必须满足互斥性。

所以JUC下就提供了一个ReentrantReadWriteLock,读写锁。这个锁的特点,就是读读可以一起操作,但是只要涉及到了写操作,就必须保证互斥。

11、ReentrantReadWriteLock如何基于AQS实现的?

lock锁,无论是读锁还是写锁,都是基于state属性判断的。

state是int,占32个bit为,将高16为,作为读锁的标识,低16位,作为写锁的标识。

如果线程要拿读锁,只需要确认没有写线程在持有写锁资源,并且队列中的head.next不是写锁(解决写锁饥饿问题),就可以直接获取读锁资源。

写锁需要确保没有读线程在持有读锁,并且没有其他线程在持有写锁,写锁才能拿到锁资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/198330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

个体诊所电子处方系统哪个好用,推荐一款可以自由设置配方模板能够填写病历可以查询历史病历的门诊处方笺软件

一、前言 1、功能实用&#xff0c;操作简单&#xff0c;不会电脑也会操作&#xff0c;软件免安装&#xff0c;已内置数据库。 2、中医西医均可用此软件开电子处方&#xff0c;支持病历记录查询&#xff0c;药品进出库管理&#xff0c;支持配方模板一键导入电子处方。 二、电子…

Amazon CodeWhisperer 正式可用, 并面向个人开发者免费开放

文章作者&#xff1a;深度-围观 北京——2023年4月18日&#xff0c;亚马逊云科技宣布&#xff0c;实时 AI 编程助手 Amazon CodeWhisperer 正式可用&#xff0c;同时推出的还有供所有开发人员免费使用的个人版&#xff08;CodeWhisperer Individual&#xff09;。CodeWhisperer…

SAP ABAP Tree Control 对象与ALV Grid 对象关联

Tree Control 对象与ALV Grid 对象关联 在双击 Tree 对象时&#xff0c;变更ALV Trid 对象的显示&#xff0c;实现界面如图9-11 所示。 Screen 设计界面如图9-12 所示。 主程序&#xff1a; REPORT ytest36. DATA: ok_code TYPE sy-ucomm,save_ok TYPE sy-ucomm. DATA: wa_co…

【C++】map和set的使用及注意事项

map和set的使用及注意事项 1.关联式容器2. 键值对3.set3.1接口介绍3.1.1构造3.1.2迭代器3.1.3容量3.1.4修改 3.2set使用及注意事项 4.multiset5.map6.multimap349. 两个数组的交集 1.关联式容器 在初阶阶段&#xff0c;我们已经接触过STL中的部分容器&#xff0c;比如&#xf…

vue项目解决计算后浮点数精度问题

1.1 问题描述 计算出的结果本来应该为13.8386&#xff0c;但是这里因为js精度问题&#xff0c;导致后边多了一串的0000001。 1.2 使用场景 求和&#xff0c;每个物品的单价*数量 1.3 解决办法 引入第三方库Decimal 1.4 vue项目中Decimal安装步骤 1.4.1 安装Decimal np…

C语言枚举详解,typedef简介(能看懂文字就能明白系列)

系列文章目录 C语言基础专栏 笔记详解 &#x1f31f; 个人主页&#xff1a;古德猫宁- &#x1f308; 信念如阳光&#xff0c;照亮前行的每一步 文章目录 系列文章目录&#x1f308; *信念如阳光&#xff0c;照亮前行的每一步* 前言一、枚举类型的声明枚举常量三、枚举类型的优…

索尼PMW580视频帧EC碎片重组开启方法

索尼PMW580视频帧EC碎片重组开启方法 索尼PMW-580摄像机生成的MXF文件存在严重的碎片化&#xff0c;目前CHS零壹视频恢复程序MXF版、专业版、高级版已经支持重组结构体正常的碎片&#xff0c;同时也支持对于结构体破坏或者覆盖后仅存在音视频帧EC数据的重组&#xff0c;需要注…

开关电源有哪些EMI整改?|深圳比创达电子EMC

某控制产品在进行辐射发射测试时&#xff0c;发现测试结果超标&#xff0c;辐射发射测试结果如下图所示&#xff1a; 控制产品在去掉发射源之前&#xff0c;就在各外部端口采取了各种滤波措施&#xff0c;结果并无明显作用&#xff0c;即使把所有相关外部引线全部拿走(只剩下电…

菜鸟学习日记(python)——运算符

我们进行运算时&#xff0c;需要两类数据&#xff0c;操作数和运算符&#xff0c;例如&#xff1a;ab就是一个运算&#xff0c;它的操作数是a和b&#xff0c;运算符是‘’ 在python中运算符包括以下几大类&#xff1a; 算数运算符比较&#xff08;关系&#xff09;运算符赋值…

spark无法执行pi_如何验证spark搭建完毕

在配置yarn环境下的spark时&#xff0c;执行尚硅谷的以下命令发现报错&#xff0c;找不到这个也找不到那个&#xff0c;尚硅谷的代码是 bin/spark-submit \ --class org.apache.spark.examples.SparkPi \ --master yarn \ --deploy-mode cluster \ ./examples/jars/spark-exam…

k8s部署单机模式的minio

k8s部署单机模式的minio 一、说明二、yaml内容三、步骤3.1 创建资源3.2 查看启动日志3.2 查看svc并访问控制台 一、说明 项目使用minio&#xff0c;准备在k8s环境部署一套minio试用。 1.关于minio的原理和概念参考: https://mp.weixin.qq.com/s?__bizMzI3MDM5NjgwNg&mid…

Python中函数添加超时时间,Python中signal使用

from time import time, sleepimport signal# 模拟要删除5条数据,中间有超时的i 5# 超时后执行的方法def timeout_handler(signal, frame):# 引发异常raise TimeoutError("删除第" str(i) "条,超时!")# 或者执行其他操作,不往外抛异常(超时的函数不会被…

使用Spring Cloud搭建一个项目框架之父子模块的创建

前言 说实在的&#xff0c;Spring Cloud的这个系列&#xff0c;很多人都写过&#xff0c;写的比博主好的一大堆&#xff0c;网友们百度一下&#xff0c;就可以发现很多很多&#xff0c;甚至有一批都是系列文章&#xff0c;我只不过之前学过一段时间&#xff0c;但是过了一段时…

ElasticSearch基础知识

ElasticSearch是一个高扩展的分布式全文搜索引擎&#xff0c;基于Lucene作为核心实现所有索引和搜索的功能。 使用场景&#xff1a; &#xff08;1&#xff09;搜索领域&#xff1a;如维基百科、谷歌&#xff0c;全文检索等。 &#xff08;2&#xff09;网站具体内容&#xf…

聊聊 Jetpack Compose 的 “状态订阅自动刷新” -- mutableStateListOf

Jekpack Compose “状态订阅&自动刷新” 系列&#xff1a; 【 聊聊 Jetpack Compose 的 “状态订阅&自动刷新” - - MutableState/mutableStateOf 】 【 聊聊 Jetpack Compose 的 “状态订阅&自动刷新” - - remember 和重组作用域 】 【 聊聊 Jetpack Compose 的 …

腾讯云轻量应用服务器怎么安装宝塔Linux面板?

腾讯云轻量应用服务器宝塔面板怎么用&#xff1f;轻量应用服务器如何安装宝塔面板&#xff1f;在镜像中选择宝塔Linux面板腾讯云专享版&#xff0c;在轻量服务器防火墙中开启8888端口号&#xff0c;然后远程连接到轻量服务器执行宝塔面板账号密码查询命令&#xff0c;最后登录和…

洗袜子的洗衣机哪款好?最好用的迷你洗衣机推荐

内衣洗衣机是一种专门用于清洁内衣裤以及袜子等等贴身衣物的小型洗衣机。对于大部分的用户而言&#xff0c;内衣裤作为着我们日常生活中必不可少的贴身衣物&#xff0c;因此对于日常所穿内衣裤的清洁和卫生都是非常重要。不仅涉及到隐私部位的卫生安全&#xff0c;更容易影响自…

javaEE -14(10000字 JavaScript入门 - 1)

一&#xff1a;初始 JavaScript JavaScript (简称 JS)是世界上最流行的编程语言之一&#xff0c;它是一个脚本语言, 通过解释器运&#xff0c;主要在客户端(浏览器)上运行, 现在也可以基于 node.js 在服务器端运行. JavaScript 和 HTML 和 CSS 之间的关系&#xff1a; HTML…

(C++)和为s的两个数字--双指针算法

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 和为S的两个数字_牛客题霸_牛客网输入一个升序数组 array 和一个数字S&#xff0c;在数组中查找两个数&#xff0c;使得他们的和正好是S&#xff0c;如果。题目来自【牛客题霸】https://www.nowcoder.com/practice/390da4f7a…

【力扣热题100】207. 课程表 python 拓扑排序

【力扣热题100】207. 课程表 python 拓扑排序 写在最前面207. 课程表解决方案&#xff1a;判断是否可以完成所有课程的学习方法&#xff1a;拓扑排序实现步骤Python 实现性能分析结论 写在最前面 刷一道力扣热题100吧 难度中等 https://leetcode.cn/problems/course-schedule…