读写锁

Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

六眼飞鱼酱① 提交于 2019-11-26 23:28:24
Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 本文内容:读写锁 ReentrantReadWriteLock 的源码分析,基于 Java7/Java8。 阅读建议:虽然我这里会介绍一些 AQS 的知识,不过如果你完全不了解 AQS,看本文就有点吃力了。 目录 使用示例 ReentrantReadWriteLock 总览 源码分析 读锁获取 读锁释放 写锁获取 写锁释放 锁降级 总结 使用示例 下面这个例子非常实用,我是 javadoc 的搬运工: // 这是一个关于缓存操作的故事 class CachedData { Object data; volatile boolean cacheValid; // 读写锁实例 final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { // 获取读锁 rwl.readLock().lock(); if (!cacheValid) { // 如果缓存过期了,或者为 null // 释放掉读锁,然后获取写锁 (后面会看到,没释放掉读锁就获取写锁,会发生死锁情况) rwl

并发数据结构 : .NET Framework 中提供的读写锁

て烟熏妆下的殇ゞ 提交于 2019-11-26 21:43:18
在多线程编程时,开发人员经常会遭遇多个线程读写某个资源的情况。这就需要进行线程同步来保证线程安全。一般情况下,我们的同步措施是使用锁机制。但是,假如线程只对资源进行读取操作,那么根本不需要使用锁;反之,假如线程只对资源进行写入操作,则应当使用互斥锁(比如使用 Monitor 类等)。还有一种情况,就是存在多个线程对资源进行读取操作,同时每次只有一个线程对资源进行独占写入操作。这正是本文主题--读写锁的用武之地。 ReaderWriterLock 类 .NET Framework BCL 在 1.1 版本时,给我们提供了一个 ReaderWriterLock 类来面对此种情景。但是很遗憾,Microsoft 官方不推荐使用该类。Jeffrey Richter 也在他的《CLR via C#》一书中对它进行了严厉的批判。下面是该类不受欢迎的主要原因: 性能。这个类实在是太慢了。比如它的 AcquireReaderLock 方法比 Monitor 类的 Enter 方法要慢 5 倍左右,而等待争夺写锁甚至比 Monitor 类慢 6 倍。 策略。假如某个线程完成写入操作后,同时面临读线程和写线程等待处理。ReaderWriterLock 会优先释放读线程,而让写线程继续等待。但我们使用读写锁是因为存在大量的读线程和非常少的写线程,这样写线程很可能必须长时间地等待,造成写线程饥饿

JUC之ReadWriteLock

◇◆丶佛笑我妖孽 提交于 2019-11-26 14:31:42
JUC之读写锁解读 文章目录 JUC之读写锁解读 一、什么是读写锁 二、读写锁的实现 三、升降级 1、锁降级 2、锁升级 四、使用场景 一、什么是读写锁 ​ 读写锁实现的功能就是“读写分离”,读可以并发读,写只能串行写,同时,读的时候不能写,写的时候不能读。但是,如何控制读与写,需要我们手动在读代码块上加读锁,写代码上加写锁。 二、读写锁的实现 ​ 这里我主要讲一些内部实现原理。 读为共享锁 final boolean tryReadLock ( ) { Thread current = Thread . currentThread ( ) ; for ( ; ; ) { int c = getState ( ) ; //判断是否此时有写锁。 if ( exclusiveCount ( c ) != 0 && getExclusiveOwnerThread ( ) != current ) return false ; //读锁的共享数量 int r = sharedCount ( c ) ; if ( r == MAX_COUNT ) throw new Error ( "Maximum lock count exceeded" ) ; //尝试CAS if ( compareAndSetState ( c , c + SHARED_UNIT ) ) { if ( r == 0