本文基於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();
}
}
運行結果如下圖所示:

