= readWriteLock.readLock(); readLock.lock(); try{ //读操作 }finally { writeLock.unlock(); } }).start(); } readLock lock() readLock是通过共享锁来实现的。lock()方法会调用acquireShared()方法。所以我们直接分析acquireShared()方法。 接下来我们继续分析readLock的unlock()方法。 小结 1.ReentrantReadWriteLock的readLock是支持重入的。 2.ReentrantReadWriteLock的readLock是通过AQS的共享锁来实现的。
1.读写锁使用 在 Java 语言中,读写锁是使用 ReentrantReadWriteLock 类来实现的,其中: ReentrantReadWriteLock.ReadLock 表示读锁,它提供了 readLock = readWriteLock.readLock(); // 获得写锁 final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock (); // 读锁使用 readLock.lock(); try { // 业务代码... } finally { readLock.unlock(); } // 写锁使用 writeLock.lock readLock = readWriteLock.readLock(); Thread t1 = new Thread(() -> { readLock.lock(); try { readLock = readWriteLock.readLock(); // 创建写锁 final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock
其中它的实现类:ReentrantReadWriteLock--顾名思义是可重入的读写锁,允许多个读线程获得ReadLock,但只允许一个写线程获得WriteLock 读写锁的机制: "读-读" 不互斥 ReadWriteLock rtLock = new ReentrantReadWriteLock(); rtLock.readLock().lock(); System.out.println(" cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock ().unlock(); } } } 以上代码加锁的顺序为: 1. rwl.readLock().lock(); 2. rwl.readLock().unlock(); 3. rwl.writeLock ().lock(); 4. rwl.readLock().lock(); 5. rwl.writeLock().unlock(); 6. rwl.readLock().unlock(); 以上过程整体讲解
但是 ReentrantReadWriteLock 拥有读锁(ReadLock)和写锁(WriteLock),它们分别都实现了 Lock。 /** Inner class providing readlock */ private final ReentrantReadWriteLock.ReadLock readerLock; new FairSync() : new NonfairSync(); readerLock = new ReadLock(this); writerLock = new = lock.readLock(); private final Lock writeLock = lock.writeLock(); ...... } 在缓存的读操作时,使用读锁。 = null && persistence.containsKey(key)); } finally { readLock.unlock();
概述在ReentrantReadWriteLock的双子星架构中,ReadLock(读锁)扮演着“共享资源守护者”的角色。 文章被收录于专栏:云时代Java开发:原理、实战与优化第一章:ReadLock的定位与核心职责1.1外观模式下的轻量级代理ReadLock是ReentrantReadWriteLock的一个内部静态类, 关键约束:ReadLock的存在完全依赖于ReentrantReadWriteLock的整体设计,无法脱离其上下文使用。 由于允许多个读线程同时持有读锁,且每个线程可重入(多次获取),ReadLock必须记录:哪些线程持有读锁;每个线程的重入次数。 如果觉得本文助你深入理解ReadLock,记得点赞、收藏,并转发给团队伙伴——一起构建更强大的并发系统!
然后就是总结这个锁机制的特性了: (a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想。 (b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的持有。 反过来ReadLock想要升级为WriteLock则不可能,为什么?参看(a),呵呵. (d).不管是ReadLock还是WriteLock都支持Interrupt,语义与ReentrantLock一致。 =readWriteLock.readLock(); readLock.lock();try{ System.out.println(“线程名称:”+Thread.currentThread().
ReadWriteLock ReadWriteLock也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个资源可以被多个线程同时读,或者被一个线程写,但是不能同时存在读和写线程 读锁:共享锁 readLock **写锁:**独占锁 writeLock 读写锁 : 一个资源可以被多个读的线程进行访问 ,或者可以被一个写的线程访问, 但是不能同时存在读和写进程 ,读写互斥,读读共享 ().lock(); 解锁 lock.writeLock().unlock(); lock.readLock().unlock(); class MyCacheLock { private readLock = lock.readLock(); //写锁 ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock readLock = lock.readLock(); //写锁 ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock
readLock = lock.readLock(); ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock(); writeLock() { return writerLock; } public ReentrantReadWriteLock.ReadLock readLock() { return readerLock ; } 复制代码可以看到用到了WriteLock和ReadLock两个静态内部类,他们对锁的实现如下: public static class ReadLock implements Lock, java.io.Serializable 而ReadLock和Semaphore一样,使用了共享锁。 在上面的代码中,ReadLock和WriteLock使用了同一个AQS,那么在ReentrantReadWriteLock中又是怎么控制读锁和写锁关系的呢?
new FairSync() : new NonfairSync(); readerLock = new ReadLock(this); writerLock = new readLock = reentrantReadWriteLock.readLock(); //1、 获取到写锁 writeLock.lock(); System.out.println //3、释放写锁 writeLock.unlock(); //4、 释放读锁 readLock.unlock(); } } /** * 获取到了写锁 readLock = reentrantReadWriteLock.readLock(); //1、 获取到读锁 readLock.lock(); System.out.println =rwl.readLock(); public static void main(String[] args) { } public Object get(String id
2.基本使用ReentrantReadWriteLock 锁分为以下两种:ReentrantReadWriteLock.ReadLock 表示读锁:它提供了 lock 方法进行加锁、unlock 方法进行解锁 readLock = readWriteLock.readLock();// 获得写锁final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock ();// 读锁使用readLock.lock();try { // 业务代码...} finally { readLock.unlock();}// 写锁使用writeLock.lock( readLock = readWriteLock.readLock();Thread t1 = new Thread(() -> { readLock.lock(); try { readLock = readWriteLock.readLock();// 创建写锁final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock
读写锁接口:ReadWriteLock,它的具体实现类为:ReentrantReadWriteLock 通过readlock() 和 writelock()来获得读锁和写锁 进行加解锁操作; 其中它的实现类:ReentrantReadWriteLock--顾名思义是可重入的读写锁,允许多个读线程获得ReadLock,但只允许一个写线程获得WriteLock 读写锁的机制: "读-读" ReadWriteLock rtLock = new ReentrantReadWriteLock(); rtLock.readLock().lock(); System.out.println(" ().unlock(); 29 } 30 } 31 } 以上代码加锁的顺序为: 1. rwl.readLock().lock(); 2. rwl.readLock().unlock(); 3. rwl.writeLock().lock(); 4. rwl.readLock().lock(); //锁降级 5. rwl.writeLock().unlock(); 6. rwl.readLock
writeLock.unlock(); } } public BitCaskEntry get(ByteString key) { Lock readLock = rwl.readLock(); readLock.lock(); try { return map.get(key ); } finally { readLock.unlock(); } } //.. ()从map读取指定key的值,最后readLock.unlock() key_dirs bitcask-java/src/main/java/com/trifork/bitcask/BitCaskKeyDir.java ()从map读取指定key的值,最后readLock.unlock() doc BitCaskKeyDir
readLock = reentrantReadWriteLock.readLock(); private static ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock(); public static void read() { readLock.lock(); } finally { System.out.println(Thread.currentThread().getName()+"释放读锁"); readLock.unlock cacheValid) { // Must release read lock before acquiring write lock rwl.readLock } try { use(data); } finally { rwl.readLock
读锁是施加不了的,写锁释放完,读锁可以施加多个 package main import ( "log" "sync" "time" ) var LockObj sync.RWMutex func Readlock LockObj.Unlock() log.Printf("写任务id: %d, [写任务完成-释放]", id) } func read() { for i := 0; i < 10; i++ { go Readlock WriteLock(i) } } // 先启动写锁 func writeFirst() { go WriteLock(1) time.Sleep(1 * time.Second) go Readlock (1) go Readlock(2) go Readlock(3) go Readlock(4) go Readlock(5) } func readFirst() { go Readlock (1) go Readlock(2) go Readlock(3) go Readlock(4) go Readlock(5) time.Sleep(1 * time.Second) go
(); /** * 读取缓存 * @param key * @return */ public V get(K key) { readLock.lock (); try { return DATA_MAP.get(key); } finally { readLock.unlock public V get(String key) { V value = null; //读取缓存 readLock.lock(); // 1 如下代码所示 public V get(String key) { readLock.lock(); System.out.println("开始读取缓存数据....." readLock.unlock(); writeLock.lock(); // 再次检查状态,因为其他线程可能已经获取到写锁且更新了状态
().lock(); try { return cache.get(key); } finally { lock.readLock ().lock(); try { return cache.size(); } finally { lock.readLock() readLock.lock(); try { return map.get(key); } finally { readLock.unlock (); } finally { readLock.unlock(); } }}3. readLock 和 writeLock: 分别获取读锁和写锁。方法解释get(K key): 获取缓存中的值。使用读锁,允许多个读操作同时进行。
writeLock.unlock(); } } public BitCaskEntry get(ByteString key) { Lock readLock = rwl.readLock(); readLock.lock(); try { return map.get(key ); } finally { readLock.unlock(); } } //. ()从map读取指定key的值,最后readLock.unlock() key_dirs bitcask-java/src/main/java/com/trifork/bitcask/BitCaskKeyDir.java ()从map读取指定key的值,最后readLock.unlock() doc BitCaskKeyDir
写-写互斥:写写阻塞 ReadWriteLock ReentrantReadWriteLock 为ReadWriteLock接口的实现,ReadWriteLock仅定义了获取读锁和写锁的两个方法,即readLock public interface ReadWriteLock { Lock readLock(); Lock writeLock(); } 除了接口方法之外,ReentrantReadWriteLock = lock.readLock(); private static final Lock writeLock = lock.writeLock(); /** * 向 map (); try { return map.get(key); } finally { readLock.unlock(); (); try { return map.keySet(); } finally { readLock.unlock();
不同的是它还多了ReadLock内部类和WriteLock内部类,以及读写对应的成员变量和方法。 WriteLock、ReadLock内部类 前面说到ReentrantReadWriteLock的lock()、unlock()操作是分配到Write/ReadLock里面执行的。 WriteLock、ReadLock最大的不同就是WriteLock用的独占模式的方法,ReadLock用的是共享模式的方法。 有的只是writeLock()、readLock(),要先调用这个方法获取应对的锁对象,再调用lock()。 ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); rwl.readLock().lock(); rwl.readLock().unlock
实例 ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); Lock readLock = lock.readLock(); Lock x++; } finally { writeLock.unlock(); } } private void print(int time) { readLock.lock System.out.print(x + " "); } System.out.println(); } finally { readLock.unlock