Java并发编程:读写锁与普通互斥锁的深度对比

article/2025/6/6 1:17:44

在Java并发编程中,锁是实现线程安全的重要工具。其中,普通互斥锁(如synchronizedReentrantLock)和读写锁(ReentrantReadWriteLock)是两种常用的同步机制。本文将从多个维度深入分析它们的区别、适用场景及性能差异,并通过示例代码展示如何在实际项目中合理选择。

一、核心概念对比

1. 普通互斥锁(Mutex)

普通互斥锁是最基本的同步机制,它遵循"排他性"原则:

  • 同一时间仅允许一个线程访问共享资源,无论该线程是读操作还是写操作。
  • 典型实现:
    • synchronized关键字
    • ReentrantLock

示例代码

private final Lock mutex = new ReentrantLock();
private List<String> sharedList = new ArrayList<>();public void write(String data) {mutex.lock();try {sharedList.add(data);} finally {mutex.unlock();}
}public String read(int index) {mutex.lock();try {return sharedList.get(index);} finally {mutex.unlock();}
}

2. 读写锁(ReadWriteLock)

读写锁将锁分为"读锁"和"写锁",并提供更细粒度的访问控制:

  • 读锁(共享锁):允许多个线程同时获取读锁,并发读取共享资源。
  • 写锁(排他锁):同一时间仅允许一个线程获取写锁,且写锁存在时不允许任何线程获取读锁。
  • 典型实现:ReentrantReadWriteLock

示例代码

private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
private final Lock writeLock = rwLock.writeLock();
private List<String> sharedList = new ArrayList<>();public void write(String data) {writeLock.lock();try {sharedList.add(data);} finally {writeLock.unlock();}
}public String read(int index) {readLock.lock();try {return sharedList.get(index);} finally {readLock.unlock();}
}

二、关键区别详解

1. 锁的粒度与并发度

维度普通互斥锁读写锁
锁粒度粗粒度(不区分读写)细粒度(区分读写)
并发度同一时间仅一个线程访问同一时间可多个线程读或一个线程写
吞吐量低(尤其读多写少场景)高(读多写少场景显著提升)

2. 适用场景对比

场景普通互斥锁读写锁
读写操作频率接近✅ 简单高效❌ 状态管理开销可能更高
读操作远多于写操作❌ 吞吐量瓶颈✅ 并发读性能显著提升
写操作占主导✅ 实现简单❌ 需处理写锁饥饿问题
需保证强一致性✅ 读写均互斥❌ 写锁释放前可能有读线程

3. 饥饿问题

  • 普通互斥锁:公平模式下较少出现饥饿,但非公平模式可能导致某些线程长时间无法获取锁。
  • 读写锁:默认非公平模式下,写锁可能因读锁持续被获取而长时间等待(写锁饥饿)。

解决方案

// 创建公平读写锁,按请求顺序分配锁
private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);

三、性能对比测试

1. 测试环境

  • 硬件:Intel i7-8700K CPU @ 3.70GHz,16GB RAM
  • JDK:Java 17
  • 测试工具:JMH
  • 测试场景:模拟100线程并发访问,读:写比例分别为9:1、5:5、1:9

2. 测试结果

读:写比例普通互斥锁吞吐量(ops/sec)读写锁吞吐量(ops/sec)性能提升
9:154,231187,629~246%
5:582,14595,312~16%
1:978,32162,419-20%

3. 结果分析

  • 读多写少场景:读写锁通过允许多线程并发读,显著提升吞吐量。
  • 读写均衡场景:读写锁的性能优势减弱,因其状态管理开销高于普通互斥锁。
  • 写多场景:读写锁的性能甚至低于普通互斥锁,因此时写锁的排他性导致锁竞争加剧。

四、读写锁的进阶特性

1. 锁降级(Write→Read)

写锁可降级为读锁,保证数据可见性:

public void upgradeExample() {writeLock.lock();try {// 写操作...// 降级为读锁readLock.lock();try {// 释放写锁,但仍持有读锁writeLock.unlock();// 执行读操作...} finally {readLock.unlock();}} finally {if (writeLock.isHeldByCurrentThread()) {writeLock.unlock();}}
}

2. 锁升级(Read→Write)

不推荐直接升级读锁为写锁,可能导致死锁:

public void wrongUpgrade() {readLock.lock();try {// 错误示例:不可直接升级读锁为写锁// 会导致死锁(需先释放读锁)writeLock.lock(); try {// ...} finally {writeLock.unlock();}} finally {readLock.unlock();}
}

五、最佳实践建议

1. 选择策略

  • 优先考虑读写锁:当读操作占比超过70%时,读写锁通常能带来显著性能提升。
  • 谨慎使用公平模式:公平模式会降低吞吐量,仅在需严格避免饥饿时使用。
  • 避免锁升级:如需同时读写,建议先获取写锁,再降级为读锁。

2. 性能优化

  • 分段锁:对大型数据结构分区加锁(如ConcurrentHashMap的实现)。
  • 读写分离:将读操作和写操作分发到不同的服务实例。
  • 异步写回:对写操作性能敏感的场景,可将写操作异步化(如写入队列后立即返回)。

六、总结

普通互斥锁和读写锁各有其适用场景,合理选择能显著提升系统性能:

场景推荐锁类型关键理由
缓存系统(读多写少)ReentrantReadWriteLock并发读性能提升明显
计数器更新(写操作频繁)ReentrantLock读写锁状态管理开销反而降低性能
强一致性要求的金融系统synchronized/ReentrantLock避免读写锁的并发读带来的一致性问题
配置中心(读操作占绝对主导)StampedLock(乐观读)进一步提升无竞争读的性能

在实际开发中,建议通过JMH等工具进行性能基准测试,验证锁选择的合理性。同时,注意监控锁竞争情况(如通过JVM工具查看锁等待时间),及时调整锁策略。


http://www.hkcw.cn/article/chDaKPiOkV.shtml

相关文章

aardio 图像识别

今天终于学会了编程中的 OCR 技术&#xff01;原来计算机真的能识别图片里的文字&#xff0c;这种让程序 "看懂" 图像的能力太神奇了&#xff0c;赶紧把学习过程记录下来。 一、初识OCR&#xff1a;让程序读懂图片文字 &#xff08;一&#xff09;简单识别实验 OC…

【北邮 操作系统】第十二章 文件系统实现

一、文件的物理结构 1.1 文件块、磁盘块 类似于内存分页&#xff0c;磁盘中的存储单元也会被分为一个个“块/磁盘块/物理块”。很多操作系统中&#xff0c;磁盘块的大小与内存块、页面的大小相同 内存与磁盘之间的数据交换(即读/写操作、磁盘I/0)都是以“块”为单位进行的。即…

VS2022下C++ Boost库安装与使用使用

一.Boost概述 1.简介 Boost 是一个广泛使用的 C 库集合&#xff0c;提供了许多高质量、可移植、高效的工具和组件&#xff0c;被视为 C 标准库的延伸。自 1998 年成立以来&#xff0c;Boost 已成为 C 社区的核心资源&#xff0c;许多 Boost 库通过实践验证后被纳入 C 标准&am…

Unity-UI组件详解

今天我们来学习Unity的UI的详解&#xff0c;这部分的内容相对较少&#xff0c;对于程序员来说主要的工作是负责将各种格式的图片呈现在显示器上并允许操作这些图片。 本篇帖子的理论依据依然是官方开源的UGUI代码&#xff0c;网址为&#xff1a;GitHub - Unity-Technologies/u…

化工厂爆炸事件看制造业AI转型

一、事件警示&#xff1a;化工制造安全风险不容忽视 近日&#xff0c;某化学有限公司发生事故。涉事工厂主体工程建设有2座硝化装置区&#xff0c;1座加氢装置区&#xff0c;均属于危险工艺生产装置。硝化反应通常属于强放热反应&#xff0c;原料及产物具有爆炸危险性&#xf…

Ubuntu系统安装与配置NTP时间同步服务

Ubuntu系统安装与配置NTP时间同步服务 一、NTP服务介绍NTP服务简介工作原理系统环境准备检查当前时间状态二、方案选择:systemd-timesyncd vs ntpd三、使用systemd-timesyncd时间同步1. 方案介绍2. 配置优化3. 应用配置4. 验证状态5. 检查当前时间状态6. 查看当前实践四、使用…

【小红书】API接口,获取笔记核心数据

小红书笔记核心数据API接口详解 - 深圳小于科技提供专业数据服务 深圳小于科技&#xff08;官网&#xff1a;https://www.szlessthan.com&#xff09;推出的小红书笔记核心数据API接口&#xff0c;为开发者提供精准的笔记互动数据分析能力&#xff0c;助力内容运营与商业决策。…

ElasticStack技术之logstash介绍

一、什么是Logstash Logstash 是 Elastic Stack&#xff08;ELK Stack&#xff09;中的一个开源数据处理管道工具&#xff0c;主要用于收集、解析、过滤和传输数据。它支持多种输入源&#xff0c;如文件、网络、数据库等&#xff0c;能够灵活地对数据进行处理&#xff0c;比如…

InternLM2/LM2.5/ViT/VL1.5/VL2.0笔记: 核心点解析

00 前言 本文主要是记录一下关于多模态大模型InternLM/InternVL系列的一些要点的理解。还是那句话&#xff0c;好记性&#xff0c;不如烂笔头。本文当成个人笔记用&#xff0c;行文风格和先前写的LLaVA系列一致。本文的重点是讲解多模态模型InternVL 1.5&#xff0c;但是Intern…

帝可得 - 设备管理

一. 需求说明 设备管理主要涉及到三个功能模块&#xff0c;业务流程如下&#xff1a; 新增设备类型: 允许管理员定义新的售货机型号&#xff0c;包括其规格和容量。 新增设备: 在新的设备类型定义后&#xff0c;系统应允许添加新的售货机实例&#xff0c;并将它们分配到特定的…

建设指南 | Cloud Apps + AI Apps端到端智能应用开发平台

在“云AI”作为基础设施的时代&#xff0c;研发、运维、信息化等部门&#xff0c;通常会面临的棘手问题都有哪些&#xff1a; 算力资源难以统一调度和管理&#xff1b;AI算法研发环境搭建复杂&#xff1b;不同模型部署方式繁杂&#xff0c;统一监控难&#xff1b;AI应用开发效…

【灵动Mini-F5265-OB】vscode+gcc工程创建、下载、调试

【前言】 【灵动Mini-F5265-OB】在官方的例程中提供了mdk、IAR的开发环境&#xff0c;使用起来非常方便。有位大佬也提供了一个gcc的示例&#xff0c;但是我使用vscode的keil插件进行工程创建&#xff0c;但是提示pack是对不上的。所以我决定重新创建我的vscode来创建开发环境。…

【AI论文】VF-Eval:评估多模态大型语言模型(MLLM)在生成人工智能生成内容(AIGC)视频反馈方面的能力

摘要&#xff1a;多模态大型语言模型&#xff08;MLLMs&#xff09;最近在视频问答领域得到了广泛研究。然而&#xff0c;现有的大多数评估都侧重于自然视频&#xff0c;而忽视了合成视频&#xff0c;例如人工智能生成的内容&#xff08;AIGC&#xff09;。与此同时&#xff0c…

Docker 镜像(或 Docker 容器)中查找文件命令

在 Docker 镜像&#xff08;或 Docker 容器&#xff09;中运行如下两个命令时&#xff1a; cd / find . -name generate.py它们的含义如下&#xff0c;我们来一行一行详细拆解&#xff0c;并结合例子讲解&#xff1a; ✅ 第一行&#xff1a;cd / ✅ 含义 cd 是“change dire…

DiskGenius专业版v6.0.1.1645:分区管理、数据恢复、备份还原,一应俱全!

各位小伙伴&#xff0c;大家好&#xff01;今天阿灿给大家带来一款超好用的分区工具&#xff0c;DiskGenius专业版。这款工具堪称电脑管理界的“瑞士军刀”&#xff0c;功能强大&#xff0c;现在出了新版本v6.0.1.1645&#xff0c;简繁中文单文件便携版&#xff0c;使用超方便。…

‌CDGP|数据治理的低效性:企业AI落地的另一大挑战

在数字化转型的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动企业创新发展的重要力量。然而&#xff0c;尽管AI技术具有巨大的潜力和优势&#xff0c;但许多企业在尝试落地AI项目时却面临着重重挑战。其中&#xff0c;数据治理的低效性尤为突出&#xff0c;…

linux学习第19、20天(父子进程)

ps ajx -->查看pid&#xff0c;ppid&#xff0c;gid&#xff0c;sid 父子进程 父子进程相同&#xff1a; 刚fork后&#xff0c;data段、text段、堆&#xff0c;栈、环境变量、全局变量、进程工作目录位置、信号处理方式 父子进程不同&#xff1a; 进程id、返回值、各自的…

AI写作革命:重塑创作未来

人工智能写作技术&#xff1a;革新创作方式的智能利器 人工智能写作技术&#xff08;AI写作技术&#xff09;是指利用自然语言处理&#xff08;NLP&#xff09;、机器学习&#xff08;ML&#xff09;等人工智能技术&#xff0c;辅助或自动化完成文本的创作、编辑与优化。这一技…

法律大语言模型(Legal LLM)技术架构

目录 摘要 1 法律AI大模型技术架构 1.1 核心架构分层 1.2 法律知识增强机制 2 关键技术突破与对比 2.1 法律专用组件创新 2.2 性能对比(合同审查场景) 3 开发部署实战指南 3.1 环境搭建流程 3.2 合同审查代码示例 4 行业应用与挑战 4.1 典型场景效能提升 4.2 关…

深入理解 C# Razor Pages:构建现代 Web 应用的利器

在现代 Web 开发中&#xff0c;选择合适的框架至关重要。ASP.NET Core 提供了多种开发模式&#xff0c;其中 Razor Pages 因其简单性、高效性和易用性&#xff0c;成为构建页面导向 Web 应用的首选方案。相比于传统的 MVC&#xff08;Model-View-Controller&#xff09;模式&am…