/**
* 讀寫鎖ReentrantReadWriteLock
* 讀寫分離可以有效地減少鎖的競爭
* 在ReentrantLock中如果給讀線程加鎖,那麼寫線程就需要等待
* 給寫線程加鎖,那麼讀線程就得等待
* 這顯然是不合理的,因爲讀操作不會對數據的完整性破壞。
* 所以在讀的次數遠遠大於寫的次數的時候,使用讀寫鎖子
* @author beiyaoyao
*/
public class ReadWriteLockDemo {
private static Lock lock = new ReentrantLock();
private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
private static Lock readLock = reentrantReadWriteLock.readLock();
private static Lock writeLock = reentrantReadWriteLock.readLock();
private int value;
public Object readMission(Lock lock) throws InterruptedException {
try {
//描述讀操作
lock.lock();
Thread.sleep(1000);
return value;
} finally {
lock.unlock();
}
}
public void writeMission(Lock lock,int num) throws InterruptedException {
try {
//描述寫操作
lock.lock();
Thread.sleep(1000);
value = num;
System.out.println(value);
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
final ReadWriteLockDemo readWriteLockDemo = new ReadWriteLockDemo();
//讀線程
Runnable readThread = new Runnable() {
@Override
public void run() {
try {
//兩把鎖子交替使用
// readWriteLockDemo.readMission(readLock);
readWriteLockDemo.readMission(lock);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//寫線程
Runnable writeThread = new Runnable() {
@Override
public void run() {
try {
//兩把鎖子交替使用
// readWriteLockDemo.writeMission(writeLock,new Random().nextInt());
readWriteLockDemo.writeMission(lock,new Random().nextInt());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//誇張的例子 讀18次
for(int i = 0 ; i < 18 ; i ++){
new Thread(readThread).start();
}
//寫2次
for(int i = 0 ; i < 2 ; i ++){
new Thread(writeThread).start();
}
}
}
如果使用重入鎖,那麼這段程序的執行時間在20秒左右
如果使用讀寫鎖,那麼這段程序的執行時間在2秒左右