目錄頁:https://blog.csdn.net/u011294519/article/details/88367808
1. ReentrantReadWriteLock
1.1. 小聲嗶嗶
見名知意,這是一種讀寫鎖,其實在很多情況下,我們對數據的讀取次數遠遠大於更新修改的次數(比如緩存),而其實在多個線程只是讀取數據的時候我們完全沒必要加鎖。讀寫鎖在寫線程訪問的時候,所有的讀和寫都被阻塞。
1.2. 主要方法
構造方法: ReentrantReadWriteLock()默認初始化非公平鎖的實例
夠着方法:ReentrantReadWriteLock(boolean fair)若傳入的參數fair爲true則初始化公平鎖,若傳入false則初始化非公平鎖
ReentrantReadWriteLock.WriteLock writeLock():返回讀鎖
ReentrantReadWriteLock.ReadLock readLock():返回寫鎖
1.3. 上代碼
1.3.1. 簡單demo
先開個開胃菜比對一下ReentrantReadWriteLock和synchronized性能
package com.concurrent.aqslock.part9.tryrw;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 簡單的demo,比對ReentrantReadWriteLock和synchronized性能
*/
public class RwDemo {
private ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock getLock = lock.readLock();
private final Lock setLock = lock.writeLock();
private int number;
// 使用synchronized對象鎖進行讀取鎖定
public synchronized int synGetNumber() {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return number;
}
// 使用synchronized對象鎖進行修改鎖定
public synchronized void synSetNumber(int number) {
try {
Thread.sleep(10);
this.number = number;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 使用ReentrantReadWriteLock的讀鎖進行讀取鎖鎖定
public int rwGetNumber() {
try {
getLock.lock();
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
getLock.unlock();
}
return number;
}
// 使用ReentrantReadWriteLock的寫鎖進行寫鎖鎖定
public void rwSetNumber(int number) {
try {
setLock.lock();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
setLock.unlock();
}
this.number = number;
}
public static void main(String[] arg0) {
RwDemo rwDemo = new RwDemo();
for (int i = 0; i < 5; ++i) {
for (int k = 0; k < 3; ++k) {
new Thread(() -> {
long start = System.currentTimeMillis();
for (int j = 0; j <= 10; ++j) {
//rwDemo.rwGetNumber();
rwDemo.synGetNumber();
}
System.out.println(Thread.currentThread().getName()
+ "讀商品數據耗時:" + (System.currentTimeMillis() - start) + "ms---------");
}).start();
}
new Thread(() -> {
long start = System.currentTimeMillis();
for (int j = 0; j <= 10; ++j) {
Random r = new Random();
//rwDemo.rwSetNumber(r.nextInt());
rwDemo.synSetNumber(r.nextInt());
}
System.out.println(Thread.currentThread().getName()
+ "寫商品數據耗時:" + (System.currentTimeMillis() - start) + "ms---------");
}).start();
}
}
}
代碼位置:aqs-lock模塊的part9
運行結果:
使用ReentrantReadWriteLock讀寫鎖
使用synchronized對象鎖
可以明顯的看出性能差距