本文基于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();
}
}
运行结果如下图所示:

