ReentrantReadWriteLock与ReentrantLock对比分析
来源:互联网 发布:希腊罗马神话 知乎 编辑:程序博客网 时间:2024/05/17 09:04
一.前言
ReentrantReadWriteLock与ReentrantLockde的关系并不是雷峰塔与雷锋的关系。
个人理解:
synchronized ——> ReentrantLock ——> ReentrantReadWriteLock是JVM逐渐向程序员放权的过程。
synchronized是将线程管理的操作全部交给了JVM,开发人员不需要关心线程的锁、线程切换等细节,反正在方法上或类上加上这个关键字就线程安全了。但是JVM对synchronized的实现并不高效,例如:synchronized是采用公平锁,操作会排一个队按顺序执行,来保证执行顺序。(会消耗更多的时间来排队)
而不公平情况下,是无序状态允许插队,jvm会自动计算如何处理更快速来调度插队。(如果不关心顺序,这个速度会更快)
ReentrantLock是synchronized的一个改进,他将更多的权利交给了开发人员,他允许开发人员对线程做更细粒度的操作,直接操作锁。
ReentrantReadWriteLock是ReentrantLock的进一步改进,他将锁更细分为读锁和写锁,粒度更细。
二.ReentrantReadWriteLock的使用原则
总则:ReentrantReadWriteLock分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!
(a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想。
(b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的持有。反过来ReadLock想要升级为WriteLock则不可能。
(c).ReadLock可以被多个线程持有并且在作用时排斥任何的WriteLock,而WriteLock则是完全的互斥。这一特性最为重要,因为对于高读取频率而相对较低写入的数据结构,使用此类锁同步机制则可以提高并发量。
(d).不管是ReadLock还是WriteLock都支持Interrupt,语义与ReentrantLock一致。
(e).WriteLock支持Condition并且与ReentrantLock语义一致,而ReadLock则不能使用Condition,否则抛出UnsupportedOperationException异常。
三.使用示例
class CachedData { Object data; volatile boolean cacheValid; final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); try { // Recheck state because another thread might have // acquired write lock and changed state before we did. if (!cacheValid) { data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); } finally { rwl.writeLock().unlock(); // Unlock write, still hold read } } try { use(data); } finally { rwl.readLock().unlock(); } } }
class RWDictionary { private final Map<String, Data> m = new TreeMap<String, Data>(); private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); private final Lock w = rwl.writeLock(); public Data get(String key) { r.lock(); try { return m.get(key); } finally { r.unlock(); } } public String[] allKeys() { r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); } } public Data put(String key, Data value) { w.lock(); try { return m.put(key, value); } finally { w.unlock(); } } public void clear() { w.lock(); try { m.clear(); } finally { w.unlock(); } } }
- ReentrantReadWriteLock与ReentrantLock对比分析
- Java多线程synchronized、ReentrantLock、ReentrantReadWriteLock 和StampedLock 的对比
- ReentrantReadWriteLock & ReentrantLock & Synchronized 区别
- Java ReentrantLock和ReentrantReadWriteLock
- ReentrantLock和ReentrantReadWriteLock使用介绍
- ReentrantLock在JDK中的使用,以及与传统方法的对比(ArrayBlockingQueue源码分析)
- synchronized与ReentrantLock锁机制对比
- ReentrantReadWriteLock分析
- 深入理解Java并发机制(4)--AQS、ReentrantLock、ReentrantReadWriteLock源码分析
- ReentrantLock源码分析与理解
- ReentrantLock源码分析与理解
- ReentrantReadWriteLock类和ReentrantLock类的区别
- Android线程并发之ReentrantLock、ReentrantReadWriteLock
- java多线程ReentrantLock、sync、ReentrantReadWriteLock性能比较
- ReentrantReadWriteLock类和ReentrantLock类的区别
- 多线程锁的使用(ReentrantLock/Condition/ReentrantReadWriteLock)
- ReentrantLock重入锁和ReentrantReadWriteLock读写分离锁
- AbstractQueuedSynchronizer与ReentrantLock。排他锁实现分析
- 华为编码规范之 注释规范
- 1101. Quick Sort
- 回顾2015.3 - 2016.9
- 欢迎使用CSDN-markdown编辑器
- Android入门五(Service)
- ReentrantReadWriteLock与ReentrantLock对比分析
- 如何给ida增加objective-c交叉引用
- 谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
- [BZOJ1040][ZJOI2008]骑士(树形dp)
- Linux Mint配置
- cocos-js判断类型
- java IO流
- 取数游戏
- python 爬虫笔记(二)