@[toc]
共享鎖和排它鎖
以 ReentranReadWriteLock 讀寫鎖為例
什麼是共享鎖和排它鎖
- 排它鎖,又稱獨佔鎖,獨享鎖 synchronized就是一個排它鎖
- 共享鎖,又稱為讀鎖,獲得共享鎖後,可以查看,但無法刪除和修改數 據, 其他線程此時業獲取到共享鎖,也可以查看但是 無法修改和 刪除數據
- 共享鎖和排它鎖典型是ReentranReadWriteLock 其中,讀鎖是共享鎖,寫鎖是 排它鎖
讀寫鎖的作用
在沒有讀寫鎖之前,我們使用的是ReentrantLock ,雖然我們保證了線程安全,,但是業浪費了一定的資源,多個讀操作同時進行,是不會出現線程安全問題
讀寫鎖的規則
- 讀寫鎖只是一把鎖,可以通過2種方式鎖定,讀鎖定和寫鎖定
- 多個線程取請求讀鎖,都可以請求到的
如果一個線程獲取到了讀鎖,其他線程需要寫鎖,申請的寫鎖必須得等讀鎖釋放
總結 : 要麼多讀,要麼一寫,二者不可共存
ReentranReadWriteLock 具體用法
上代碼
package com.yxl.po;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class a {
//創建讀寫鎖
private static ReentrantReadWriteLock reentrantReadWriteLock=new ReentrantReadWriteLock();
//創建讀鎖
private static ReentrantReadWriteLock.ReadLock readLock=reentrantReadWriteLock.readLock();
//創建寫鎖
private static ReentrantReadWriteLock.WriteLock writeLock=reentrantReadWriteLock.writeLock();
//讀鎖方法
private static void read(){
readLock.lock();
try {
System.out.println(Thread.currentThread().getName()+"得到了讀鎖");
Thread.sleep(1000);
}catch (Exception e){
}finally {
System.out.println(Thread.currentThread().getName()+"釋放讀鎖");
readLock.unlock();
}
}
//寫鎖方法
private static void write(){
writeLock.lock();
try {
System.out.println(Thread.currentThread().getName()+"得到了寫鎖");
Thread.sleep(1000);
}catch (Exception e){
}finally {
System.out.println(Thread.currentThread().getName()+"釋放寫鎖");
writeLock.unlock();
}
}
public static void main(String[] args) {
new Thread(()->read(),"T1").start();
new Thread(()->read(),"T2").start();
new Thread(()->write(),"T3").start();
new Thread(()->write(),"T4").start();
}
}
- 從運行結果可以、看到 讀鎖 線程1 和 2 都可以一起獲取到 而寫鎖必須得獲取釋放,下一個線程才能獲取
讀鎖和寫鎖的交互方式
- 插隊: 不允許讀鎖插隊
- 升降級 允許降級,不允許升級,
是否是公平策略 ,和 ReentranLock 一樣 傳入true ,false
- 底層設計思路和ReentranLock 一樣
公平鎖: 不允許插隊
非公平鎖:
- 寫鎖可以隨時插隊
- 讀鎖僅在等待隊列頭節點不是想獲取寫鎖到時候可以插隊