本文基于ReentrantReadWriteLock来说明它自己的锁升级的策略。
读写锁总结
这里我先说明下读写锁进行下总结:
要么多读,要么一写;读写锁适用去读多写锁的情况。
公平情况下,读写锁都不能插队;非公平情况下,写锁可以插队,读锁只有在头结点不是写等待的情况下插队。
读锁是否可以升级到写锁
这里我先给出结论:读锁不可以升级为写锁;若两个线程的读锁都想升级写锁,则需要对方都释放自己锁,而双方都不释放,就会产生死锁。
实现代码如下所示
package com.yang.lock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * 本实例演示读锁的升级 */ public class ReentrantReadWriteUpgardeDemo { private static ReentrantReadWriteLock reentrantReadWriteLock=new ReentrantReadWriteLock(false); private static ReentrantReadWriteLock.ReadLock readLock=reentrantReadWriteLock.readLock(); private static ReentrantReadWriteLock.WriteLock writeLock=reentrantReadWriteLock.writeLock(); public void upgarde(){ System.out.println(Thread.currentThread().getName()+"尝试获取读锁"); readLock.lock(); try{ System.out.println(Thread.currentThread().getName()+"获取到了读锁"); System.out.println(Thread.currentThread().getName()+"阻塞获取写锁"); writeLock.lock(); }finally { readLock.unlock(); } } public static void main(String[] args) { ReentrantReadWriteUpgardeDemo reentrantReadWriteUpgardeDemo=new ReentrantReadWriteUpgardeDemo(); new Thread(()->reentrantReadWriteUpgardeDemo.upgarde(),"线程1").start(); new Thread(()->reentrantReadWriteUpgardeDemo.upgarde(),"线程2").start(); } }
写锁是否可以降级为读锁
这里我先给出结论:写锁是可以降级为读锁的;写锁只有一个,当写锁降级为读锁时,所有的都是读。
实现代码如下所示
package com.yang.lock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * 本实例演示读锁的升级 */ public class ReentrantReadWriteDowngradeDemo { private static ReentrantReadWriteLock reentrantReadWriteLock=new ReentrantReadWriteLock(false); private static ReentrantReadWriteLock.ReadLock readLock=reentrantReadWriteLock.readLock(); private static ReentrantReadWriteLock.WriteLock writeLock=reentrantReadWriteLock.writeLock(); public void downgrade(){ System.out.println(Thread.currentThread().getName()+"尝试获取写锁"); writeLock.lock(); try{ System.out.println(Thread.currentThread().getName()+"获取到了写锁"); System.out.println(Thread.currentThread().getName()+"降级获取读锁"); readLock.lock(); try{ }finally { readLock.unlock(); } }finally { writeLock.unlock(); } } public static void main(String[] args) { ReentrantReadWriteDowngradeDemo reentrantReadWriteUpgardeDemo=new ReentrantReadWriteDowngradeDemo(); new Thread(()->reentrantReadWriteUpgardeDemo.downgrade(),"线程1").start(); new Thread(()->reentrantReadWriteUpgardeDemo.downgrade(),"线程2").start(); } }
运行结果如下图所示: