当前位置: 首页 > news >正文

Java并发编程:ReentrantReadWriteLock读写锁

前言在Java并发编程中锁机制是保证线程安全的重要手段。synchronized和ReentrantLock都是排他锁同一时刻只允许一个线程访问共享资源。但在实际业务场景中读操作往往远多于写操作如果多个读线程之间也要互相等待会严重影响系统性能。ReentrantReadWriteLock读写锁正是为了解决这个问题而设计的。它维护了一对锁读锁和写锁通过读写分离的策略大幅提升并发性能。一、读写锁的核心特性锁类型特性说明读锁共享锁多个线程可同时持有读锁写锁排他锁同一时刻只能有一个线程持有写锁读写锁遵循以下基本原则读-读共享多个读线程可以同时执行写-写互斥多个写线程不能同时执行读-写互斥读操作和写操作不能同时进行二、三种场景代码实战2.1 读读共享读锁是共享锁多个线程可以同时获取读锁互不阻塞。public class ReadReadTest { public static void main(String[] args) { MyTask myTask new MyTask(); new Thread(() - myTask.read(), t1).start(); new Thread(() - myTask.read(), t2).start(); } static class MyTask { private final ReentrantReadWriteLock lock new ReentrantReadWriteLock(); public void read() { try { lock.readLock().lock(); System.out.println(Thread.currentThread().getName() start); Thread.sleep(10000); System.out.println(Thread.currentThread().getName() end); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.readLock().unlock(); } } } }运行结果t1 start t2 start t1 end t2 end可以看到t1和t2几乎同时开始读锁不互斥。2.2 写写互斥写锁是排他锁同一时刻只能有一个线程持有写锁。public class WriteWriteTest { public static void main(String[] args) { MyTask myTask new MyTask(); new Thread(() - myTask.write(), t1).start(); new Thread(() - myTask.write(), t2).start(); } static class MyTask { private final ReentrantReadWriteLock lock new ReentrantReadWriteLock(); public void write() { try { lock.writeLock().lock(); System.out.println(Thread.currentThread().getName() start); Thread.sleep(10000); System.out.println(Thread.currentThread().getName() end); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.writeLock().unlock(); } } } }运行结果t1 start t1 end t2 start t2 endt2必须等待t1释放写锁后才能执行写锁互斥。2.3 读写互斥读写操作互斥读操作进行时写操作必须等待反之亦然。public class ReadWriteTest { public static void main(String[] args) { MyTask myTask new MyTask(); Thread t1 new Thread(() - myTask.read(), t1); Thread t2 new Thread(() - myTask.write(), t2); t1.start(); // 确保t1先获取读锁 Thread.sleep(2000); t2.start(); } static class MyTask { private final ReentrantReadWriteLock lock new ReentrantReadWriteLock(); public void read() { try { lock.readLock().lock(); System.out.println(Thread.currentThread().getName() start); Thread.sleep(10000); System.out.println(Thread.currentThread().getName() end); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.readLock().unlock(); } } public void write() { try { lock.writeLock().lock(); System.out.println(Thread.currentThread().getName() start); Thread.sleep(10000); System.out.println(Thread.currentThread().getName() end); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.writeLock().unlock(); } } } }运行结果t1 start t1 end t2 start t2 endt2必须等待t1读完才能开始写读写互斥。三、读写锁的适用场景读写锁特别适合读多写少的业务场景场景是否适用原因缓存系统✅ 非常适合大量读操作偶尔更新配置中心✅ 非常适合配置读取频繁变更极少计数器❌ 不适合读写比例接近1:1账户转账❌ 不适合写操作频繁锁竞争严重四、注意事项4.1 锁降级ReentrantReadWriteLock支持锁降级写锁可以降级为读锁但读锁不能升级为写锁。// 锁降级允许 writeLock.lock(); readLock.lock(); // 写锁持有状态下获取读锁 writeLock.unlock(); // 仍然持有读锁 // 锁升级不允许会死锁 readLock.lock(); writeLock.lock(); // 线程永久阻塞5.2 公平性选择与ReentrantLock一样读写锁也支持公平/非公平模式非公平模式默认吞吐量更高但可能造成写线程饥饿公平模式线程按请求顺序获取锁避免饥饿// 公平读写锁 ReentrantReadWriteLock fairLock new ReentrantReadWriteLock(true);5.3 重入特性读写锁支持锁重入但需要注意读线程可以重复获取读锁写线程可以重复获取写锁也可以获取读锁锁降级六、总结对比项ReentrantLockReentrantReadWriteLock锁类型排他锁读写分离读并发不并发并发写并发不并发不并发适用场景读写均衡读多写少最佳实践在读操作远多于写操作的场景下优先考虑使用ReentrantReadWriteLock它可以显著提升系统吞吐量让并发性能得到质的飞跃。
http://www.gsyq.cn/news/1370981.html

相关文章:

  • 终极鸣潮优化指南:3分钟解锁120FPS与专业抽卡分析
  • 具身智能的应用场景有哪些
  • HS2游戏体验完整解决方案:技术增强与本地化终极指南
  • 忘记压缩包密码怎么办?ArchivePasswordTestTool:你的终极免费密码恢复解决方案
  • CleanMyWechat:你的微信磁盘空间救星,三步告别几十GB的缓存困扰
  • Windows 10/11 上从零搞定 OpenCDA 自动驾驶仿真环境:CARLA 0.9.14 + PyTorch + SUMO 保姆级配置流程
  • 终极跨平台游戏资源管理器:VPKEdit完全指南
  • 可视化 React 水合(Hydration)问题
  • 天际模组编排师:用LOOT主列表告别游戏崩溃的智能解决方案
  • Loop:重新定义macOS窗口管理的终极免费工具,告别杂乱桌面
  • Burp Suite小白挖洞实战:公益漏洞挖掘的最小可行闭环
  • 长期使用Taotoken Token Plan套餐在项目开发中的成本节省体感
  • App爬虫实战:突破SSL Pinning、动态签名与设备指纹的五层反爬
  • 智能音箱AI改造:3步让你的小爱音箱变身AI语音助手
  • OBS直播计时器插件:6种计时模式让你轻松掌控直播节奏
  • 如何永久解锁Cursor Pro功能:面向开发者的完整解决方案
  • 【企业级日志审计生死线】:为什么92%的DeepSeek用户漏配audit_policy_rule_id字段?3分钟紧急修复清单
  • 百度网盘直链解析:5分钟实现全速下载的终极指南
  • LSLib:游戏资源逆向工程的架构级解决方案
  • 对比直接使用厂商API观察Taotoken聚合调用的优势
  • 内容创作团队如何利用Taotoken调度不同模型生成素材
  • 【Gemini代码生成能力权威评测】:基于2000+真实编码场景的7大维度深度拆解
  • DeepSeek模型服务鉴权突然失效?3分钟定位JWT签名异常与OIDC配置断点(附诊断脚本)
  • 【DeepSeek生产级推理调优白皮书】:基于127个真实GPU节点压测数据的5类场景最优配置矩阵
  • 长期使用Taotoken后对其账单明细与用量分析的依赖程度
  • Real-ESRGAN-GUI完整教程:如何免费使用AI图像增强工具实现高清修复
  • 【DeepSeek缓存策略设计权威指南】:20年架构师亲授5大核心原则与3类典型场景落地实践
  • Chat2DB:用AI重构数据库交互范式,让SQL编写效率提升300%的技术革命
  • 多模态SLU评估:从数据到决策的深度解构
  • 【限时开放】Gemini CSR活动策划黄金模板包(含GDPR+AI Act双合规checklist、多语言志愿者管理看板、ESG叙事脚本生成器)