【Java JUC】读写自旋锁:共享和独占 —— 基本概念、使用场景和代码示例

news/2024/11/23 2:15:46/

目录

      • 概念
      • 示例
      • 为什么不干脆把读操作设置为无锁?

概念

读写自旋锁是一种结合了读写锁自旋锁的锁类型,可以同时支持并发读互斥写
Java中可以使用ReentrantReadWriteLock类来实现读写可重入锁,该类提供了读锁和写锁两种类型的锁,都是可重入的。由于读是不对数据造成影响的,读锁是共享的,所以读锁被称为共享锁;由于写操作是对数据的修改,存在线程安全问题,为保证线程安全,写锁是独占的,所以写锁被称为独占锁

示例

下面是使用ReentrantReadWriteLock实现读写锁的示例:

import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockDemo {private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();public void readData() {lock.readLock().lock(); // 获取读锁try {// 读取共享数据} finally {lock.readLock().unlock(); // 释放读锁}}public void writeData() {lock.writeLock().lock(); // 获取写锁try {// 修改或写入数据} finally {lock.writeLock().unlock(); // 释放写锁}}
}

在上面的示例代码中,readData方法通过调用lock.readLock()方法获取读锁,而writeData方法则通过调用lock.writeLock()方法获取写锁。
使用读写锁时,在读取共享数据时可以并发进行,即多个线程可以同时对同一段共享数据进行读取,而在修改或写入共享数据时,只有一个线程能进行操作,其他线程需要等待其完成。
需要注意的是,在使用ReentrantReadWriteLock实现读写锁时,写锁拥有最高的优先级,一旦写锁被请求,那么任何读锁或写锁的请求都会被阻塞,直到写锁完全释放(写锁现参与者本身也可以申请读锁的,这种情况下,由于写锁仍然持有,读锁的申请仍然被阻塞)

为什么不干脆把读操作设置为无锁?

那么这时候我们就会有一个疑问:既然ReentrantReadWriteLock的读锁是共享锁,那为什么不干脆把读操作设置为无锁?
想要弄清楚这个问题,首先要明白写锁的机制,写锁是一个独占锁,独占锁具有排它性,当一个线程持有写锁的时候,其他的线程所持有的读锁都会被阻塞(上面提到过)。
如果我们不为读操作加锁,那么当一个线程获取写锁在修改数据的时候,我们读到了这个修改之前的数据,然后线程修改完毕,我们会发现我们读取的内容和数据是对不上的,我们读出来和实际数据不一样的这种数据,称其为脏数据,这样就不具有同步性了(这个问题的本质和数据库脏读基本一致,后面我也会发布关于数据库的文章来详细介绍)。
但是,如果加上了读锁就不一样了,当有线程获取了写锁,在对数据进行修改的时候,其他线程获取读锁想要读取数据,就会被阻塞,等到写锁完全释放,持有读锁的线程才能读取。这样就保证了数据同步和避免读到脏数据的情况。


http://www.ppmy.cn/news/168224.html

相关文章

中睿天下参编的《中国网信产业桔皮书-数据安全》正式发布

5月28日,2023中关村论坛中关村国际技术交易大会第七届中国网信产业前锋汇成功举办,本次会议以“全球数字经济发展与数据安全关键技术”为主题,会议由中国(中关村)网络安全与信息化产业联盟主办(以下简称联盟…

HTML5+CSS3+JS小实例:简约的垂直选项卡

实例:简约的垂直选项卡 技术栈:HTML+CSS+JS 字体图标库:font-awesome 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="v…

基于springboot的闲置交易系统

一&#xff1a;系统使用到的技术栈 SpringbootVueMysqlElementUI 二&#xff1a;表结构 三&#xff1a;功能截图 四&#xff1a;源码获取

basys3芯片型号xc7a35tcpg236-1

vivado环境下创建新工程每次输入型号很麻烦&#xff0c;记录一下 xc7a35tcpg236-1

单片机之XPT2046

XPT2046是一种可以做触摸(压力)感应&#xff0c;热感应&#xff0c;光感应&#xff0c;烟雾感应等的对模拟信号转换成数字信号的芯片。 XPT2046 支持从 1.5V 到 5.25V 的低电压 I/O 接口。 电压&#xff1a;0V ~ 6V 温度&#xff1a;-40℃ ~ 85℃ 芯片模型图 控制寄存器 模式…

痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.A)- FlexSPI NOR启动时间(RT1170)...

大家好&#xff0c;我是痞子衡&#xff0c;是正经搞技术的痞子。今天痞子衡给大家介绍的是恩智浦i.MX RT1170 FlexSPI NOR启动时间。 痞子衡刚刚拿到i.MXRT1170 B0版本的芯片&#xff0c;迫不及待地在上面跑了一些A0版本上早已验证过的demo&#xff0c;功能一切正常&#xff0c…

itx机箱尺寸_讲解 ATX M-ATX ITX 各种主板尺寸

AMD Ryzen 已经发布一段时间了,不少观望的朋友也准备装机了,说到装机不得不说主板,主板尺寸大小各有不同,例如 ATX 、M-ATX 、ITX 、STX 这些标准究竟什么意思,快跟着小编一起学习吧。 主板尺寸差别大乱七八糟,粗略数了一下有十几种之多,目前常见的主要还是 ATX 、Micro…

VAPS XT开发入门教程06:新建文件介绍

本文首发于&#xff1a;VAPS XT开发入门教程06&#xff1a;新建文件介绍 我们来看一下VAPS XT的基本文件类型和格式 VAPS XT工程的所有文件都是XML格式保存的。一个页面一般会保存为两个文件*.vcls/*.vimp。vcls(v class)一般保存声明&#xff0c;比如数据结构、事件名称等等…