RelaxHeart網(wǎng) - Tec博客: 我的更多文章
ReadWriteLock
ReadWriteLock是JDK5中提供的讀寫分離鎖多艇。讀寫分離鎖可以有效地幫助減少鎖競爭狡逢,以提高系統(tǒng)性能患蹂。用鎖分離的機(jī)制來提升性能非常容易理解荤懂,比如線程A1,A2,A3進(jìn)行寫操作箍镜,B1,B2,B3進(jìn)行讀操作配椭,如果使用重入鎖或者內(nèi)部鎖(synchronized)則論路上說所有讀之間内舟、讀與寫之間匿乃、寫與寫之間都是穿行操作的桩皿。當(dāng)B1進(jìn)行讀取時(shí),B2幢炸、B3則需要等待鎖泄隔。由于讀操作并不對(duì)數(shù)據(jù)的完整性造成破壞,這種等待顯然是不合理的宛徊。因此佛嬉,讀寫鎖就有了發(fā)揮功能的余地。
在這種情況下闸天,讀寫鎖允許多個(gè)線程同時(shí)讀巷燥,使得B1,B2,B3之間真正并行。但是号枕,考慮都數(shù)據(jù)完整性缰揪,寫寫操作和讀寫操作間依然時(shí)需要相互等待和持有鎖的〈写荆總的來說钝腺,讀寫鎖的訪問約束如下表:
image.png
使用示例
如果在系統(tǒng)中,讀操作次數(shù)遠(yuǎn)遠(yuǎn)大于寫操作赞厕,則讀寫鎖就可以發(fā)揮最大的功效艳狐,提升系統(tǒng)的性能。這里我給出一個(gè)稍微夸張點(diǎn)的案例皿桑,來說明讀寫鎖對(duì)性能的幫助:
/**
* @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
* @Date: 2019-5-4 0004 9:17
* @Description: 讀寫鎖案例
*/
public class ReadWriteLockDemo {
private static Lock lock = new ReentrantLock();
private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private static Lock readLock = readWriteLock.readLock();
private static Lock writeLock = readWriteLock.writeLock();
private int val;
/**
* 處理讀操作
*
* @throws InterruptedException
*/
public Object handleRead(Lock lock) throws InterruptedException {
try {
// 模擬讀操作
lock.lock();
// 讀操作的耗時(shí)越多毫目,讀寫鎖的性能優(yōu)勢就越明顯
Thread.sleep(1000);
return val;
} finally {
lock.unlock();
}
}
/**
* 處理寫操作
*
* @throws InterruptedException
*/
public void handleWrite(Lock lock, int index) throws InterruptedException {
try {
// 模擬寫操作
lock.lock();
Thread.sleep(1000);
val = index;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
final ReadWriteLockDemo demo = new ReadWriteLockDemo();
Runnable readRunnale = new Runnable() {
@Override
public void run() {
try {
demo.handleRead(readLock);
demo.handleRead(lock);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable writeRunnable = new Runnable() {
@Override
public void run() {
try {
demo.handleWrite(writeLock, new Random().nextInt());
demo.handleWrite(lock, new Random().nextInt());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for (int i=0; i<18; i++){
new Thread(readRunnale).start();
}
for (int i=0; i<2; i++){
new Thread(writeRunnable).start();
}
}
}
總結(jié)
對(duì)于讀寫鎖訪問約束如下:
(1)讀-讀不互斥:讀讀之間不阻塞
(2)讀-寫互斥:讀阻塞寫蔬啡,寫也會(huì)阻塞讀
(3)寫-寫互斥:寫寫阻塞