目录页: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对象锁
可以明显的看出性能差距