前言 上一篇文章给和大家一起分析了ReentrantReadWriteLock的readLock的原理,相信大家对readLock的实现已经有所了解,今天我们继续分析writeLock。 writeLock源码分析 我们直接进入正题,通过源码分析加深对writeLock的理解。我们通过lock()和unlock()两个方法为入口进行分析。 小结 1.ReentrantReadWriteLock的writeLock支持重入。 2.ReentrantReadWriteLock的writeLock与读锁是冲突的,有线程获取了读锁,那么当前线程获取写锁是需要阻塞等待的(当前线程获取读锁也需要等待)。
ReentrantReadWriteLock.WriteLock 表示写锁,它提供了 lock 方法进行加锁、unlock 方法进行解锁。 writeLock = readWriteLock.writeLock(); // 读锁使用 readLock.lock(); try { // 业务代码... } finally { readLock.unlock(); } // 写锁使用 writeLock.lock(); try { // 业务代码... } finally { writeLock.unlock( writeLock = readWriteLock.writeLock(); // 使用读锁 Thread t1 = new Thread(() -> { readLock.lock(); writeLock = readWriteLock.writeLock(); Thread t1 = new Thread(() -> { writeLock.lock(); try
writeLock; synchronized (this) { writeLock = locks.get(safeKey); if (writeLock == null ) { writeLock = writeLockPool.obtain(); locks.put(safeKey, writeLock); } writeLock.interestedThreads++; } writeLock.lock.lock(); } 释放锁的时候,会把writeLock的interestedThreads 进行减一操作,如果为0了就释放锁,放入WriteLockPool中 void release(String safeKey) { WriteLock writeLock; synchronized < 1) { ... } writeLock.interestedThreads--; if (writeLock.interestedThreads
然后就是总结这个锁机制的特性了: (a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想。 (b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的持有。 反过来ReadLock想要升级为WriteLock则不可能,为什么?参看(a),呵呵. (c).ReadLock可以被多个线程持有并且在作用时排斥任何的WriteLock,而WriteLock则是完全的互斥。 =readWriteLock.writeLock(); writeLock.lock();try{ System.out.println(“线程名称:”+Thread.currentThread(
但是 ReentrantReadWriteLock 拥有读锁(ReadLock)和写锁(WriteLock),它们分别都实现了 Lock。 readlock */ private final ReentrantReadWriteLock.ReadLock readerLock; /** Inner class providing writelock */ private final ReentrantReadWriteLock.WriteLock writerLock; ReentrantReadWriteLock 在使用读锁时,其他线程可以进行读操作 new FairSync() : new NonfairSync(); readerLock = new ReadLock(this); writerLock = new WriteLock = lock.writeLock(); ...... } 在缓存的读操作时,使用读锁。
ReadWriteLock ReadWriteLock也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个资源可以被多个线程同时读,或者被一个线程写,但是不能同时存在读和写线程 读锁:共享锁 readLock **写锁:**独占锁 writeLock 读写锁 : 一个资源可以被多个读的线程进行访问 ,或者可以被一个写的线程访问, 但是不能同时存在读和写进程 ,读写互斥,读读共享 writeLock = lock.writeLock(); //锁降级 //获取写锁 writeLock.lock(); System.out.println writeLock = lock.writeLock(); //锁降级 //获取读锁 readLock.lock(); System.out.println writeLock.unlock(); readLock.unlock(); } } 不可以在读锁中写 不会停止
ReentrantReadWriteLock.ReadLock readerLock; /** 写锁 */ private final ReentrantReadWriteLock.WriteLock (this); } /** 返回用于写入操作的锁 */ public ReentrantReadWriteLock.WriteLock writeLock() { return writeLock = reentrantReadWriteLock.writeLock(); // 获取写锁 ReentrantReadWriteLock.ReadLock writeLock = reentrantReadWriteLock.writeLock(); // 获取写锁 ReentrantReadWriteLock.ReadLock =rwl.writeLock(); private Lock readLock=rwl.readLock(); public static void main(String[] args
public interface ReadWriteLock { Lock readLock(); Lock writeLock(); } 原来这是一个接口,它本身并不是锁对象 ,只是维护了一个读锁(readLock),一个写锁(writeLock)。 ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); readWriteLock.writeLock ("thread2 try to lock"); readWriteLock.writeLock().lock(); System.out.println ("thread2 lock successfully"); }).start(); readWriteLock.writeLock().unlock();
writeLock = lock.writeLock(); private int x = 0; private void count() { writeLock.lock (); try { x++; } finally { writeLock.unlock();// 保证当读的时候如果出现异常 使用ReentrantReadWriteLock读写锁的方式,会调用readLock()和writeLock()两个方法,看下他们的源码: public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } public ReentrantReadWriteLock.ReadLock readLock() { return readerLock 在上面的代码中,ReadLock和WriteLock使用了同一个AQS,那么在ReentrantReadWriteLock中又是怎么控制读锁和写锁关系的呢?
2、Lock界面主要包括ReentrantLock、ReentrantReadWriteLock、ReentrantReadWriteLock、WriteLock实现类。 实例 ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); Lock readLock = lock.readLock(); Lock writeLock = lock.writeLock(); private int x = 0; private void count() { writeLock.lock(); try { x++; } finally { writeLock.unlock(); } } private void print(int time) { readLock.lock
概述在ReentrantReadWriteLock的双子星架构中,WriteLock(写锁)扮演着“数据修改守门人”的角色。 文章被收录于专栏:云时代Java开发:原理、实战与优化第一章:WriteLock的定位与核心职责1.1外观模式下的独占代理WriteLock是ReentrantReadWriteLock的一个内部静态类 关键约束:WriteLock的独占性是ReentrantReadWriteLock一致性的基石,任何破坏此约束的行为都将导致数据损坏。 你认为WriteLock在虚拟线程时代最大的挑战是什么?是线程身份的重新定义,还是全新的独占模型?欢迎在评论区分享你的见解! 如果觉得本文助你深入理解WriteLock,记得点赞、收藏,并转发给团队伙伴——一起构建更强大、更可靠的并发系统!
ReentrantReadWriteLock.WriteLock 表示写锁:它提供了 lock 方法进行加锁、unlock 方法进行解锁。 writeLock = readWriteLock.writeLock();// 读锁使用readLock.lock();try { // 业务代码...} finally { readLock.unlock ();}// 写锁使用writeLock.lock();try { // 业务代码...} finally { writeLock.unlock();}2.1 读读不互斥多个线程可以同时获取到读锁 writeLock = readWriteLock.writeLock();// 使用读锁Thread t1 = new Thread(() -> { readLock.lock(); try writeLock = readWriteLock.writeLock();Thread t1 = new Thread(() -> { writeLock.lock(); try {
= readWriteLock.writeLock(); /** * 读取缓存 * @param key * @return */ public (); } } /** * 清空缓存 */ public void clear() { writeLock.lock(); try { DATA_MAP.clear(); } finally { writeLock.unlock(); } = readWriteLock.writeLock(); /** * 读取缓存,若缓存不存在则查找数据库并放到缓存 * @param key * @return readLock.unlock(); writeLock.lock(); // 再次检查状态,因为其他线程可能已经获取到写锁且更新了状态
*/ public static void add(SmconfigDmTaskMain info) { try { lock.writeLock public static void add(List<SmconfigDmTaskMain> infos) { try { lock.writeLock { add(info); } } finally { lock.writeLock } } } } finally { lock.writeLock initTask(Long sysTaskId, Date nextTime, Integer taskSwitch) { try { lock.writeLock
().unlock(); } } public void remove(K key) { lock.writeLock().lock(); try { cache.remove(key); } finally { lock.writeLock().unlock(); } = lock.writeLock(); public V get(K key) { try { // 获取读锁 readLock.lock (); cache.remove(key); } finally { // 释放写锁 writeLock.unlock() readLock 和 writeLock: 分别获取读锁和写锁。方法解释get(K key): 获取缓存中的值。使用读锁,允许多个读操作同时进行。
ReadWriteLock ReentrantReadWriteLock 为ReadWriteLock接口的实现,ReadWriteLock仅定义了获取读锁和写锁的两个方法,即readLock()方法和writeLock public interface ReadWriteLock { Lock readLock(); Lock writeLock(); } 除了接口方法之外,ReentrantReadWriteLock = lock.writeLock(); /** * 向 map 存入数据 * * @param key * @param value * try { return map.put(key, value); } finally { writeLock.unlock(); (); try { map.clear(); } finally { writeLock.unlock();
private boolean is_ready; public boolean put(ByteString key, BitCaskEntry ent) { Lock writeLock = rwl.writeLock(); writeLock.lock(); try { BitCaskEntry old = map.get( } else { return false; } } finally { writeLock.unlock (),对于old值为null的或者新值大于old值的才put进去,否则返回false,最后writeLock.unlock();其get方法使用readLock.lock()从map读取指定key的值, (),对于old值为null的或者新值大于old值的才put进去,否则返回false,最后writeLock.unlock();其get方法使用readLock.lock()从map读取指定key的值,
(); } 源码中readLock() 和writeLock() 的含义如下: 1、readLock():读锁。 2、writeLock():写锁,是独占锁。加了写锁的资源,不能再被其他线程读或写。换句话说,如果山已经获取了写锁,那么此时无论线程t2要申请写锁还是读锁,都必须等待t1释放写锁。 rwl.readLock().unlock(); } } //用写锁来锁定写操作 public void myWrite(Thread thread) { rwl.writeLock "正在进行写操作"); } System.out.println(thread.getName() + "===写操作完毕==="); } finally { rwl.writeLock 如果一个线程获取了写锁(writeLock().lock()) , 那么另一个线程就必须等待写锁的释放, 运行结果如图所示。 ?
private boolean is_ready; public boolean put(ByteString key, BitCaskEntry ent) { Lock writeLock = rwl.writeLock(); writeLock.lock(); try { BitCaskEntry old = map.get(key ; } else { return false; } } finally { writeLock.unlock (),对于old值为null的或者新值大于old值的才put进去,否则返回false,最后writeLock.unlock();其get方法使用readLock.lock()从map读取指定key的值, (),对于old值为null的或者新值大于old值的才put进去,否则返回false,最后writeLock.unlock();其get方法使用readLock.lock()从map读取指定key的值,
其中它的实现类:ReentrantReadWriteLock--顾名思义是可重入的读写锁,允许多个读线程获得ReadLock,但只允许一个写线程获得WriteLock 读写锁的机制: "读-读" 不互斥 ReentrantReadWriteLock(); rtLock.readLock().lock(); System.out.println("get readLock."); rtLock.writeLock ReadWriteLock rtLock = new ReentrantReadWriteLock(); rtLock.writeLock().lock(); System.out.println("writeLock ().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(); 以上过程整体讲解