文章目录
- 1.示例
- 1.1 参与角色
- 2 示例代码
- 2.1 字段说明
- 2.2 方法说明
- 2.3 值得反复多读几次的代码
- 总结
Read-Write Lock Pattern将读取与写入分开处理,在读取数据之前必须获取用来读取的锁定,而写入的时候必须获取用来写入的锁定。因为读取时实例的状态不会改变,所以多个线程可以同时读取;但是,写入会改变实例的状态,所以当有一个线程写入的时候,其它线程既不能读取与不能写入。
即读取与写入冲突 和 写入与写入冲突。
因为读取的线程之间没有冲突。因此多个Reader角色可以参与读取,提升程序性能。
1.示例
1.1 参与角色
Read-Write Lock模式的角色如下:
- Reader(读取者)参与者
Reader参与者会对SharedResource进行读。 - Writer(写入者)参与者
Writer参与者会对SharedResource进行写。 - SharedResource(共享资源)参与者
SharedResource代表Reader和Writer所共享的资源对象,SharedResource提供不改变内部状态的read操作,以及会改变内部状态的write操作。 - ReadWriteLock(读写锁)参与者
ReadWriteLock提供了对SharedResource参与者进行read操作和write操作时需要的锁定。
2 示例代码
2.1 字段说明
核心是这个实例。这个实例中定义了4个数量
• int readingReaders = 0; // 实际正在读取的线程数量
• int waitingWriters = 0; // 正在等待写入的线程数量
• int writingWriters = 0; // 实际正在写入的线程数量
• boolean preferWriter = true; // 写入优先的话,值为true
2.2 方法说明
- readLock()方法
只要preferWriter 为true,且有等待写的线程,读线程会wait。只要正在写,也会wait - readUnlock()方法
每次readUnlock()后 就会将 preferWriter设置为true。 - writeLock()方法
只要有读线程、写线程在运行,就等待。 - writeUnlock()方法
将 preferWriter设置为False。
2.3 值得反复多读几次的代码
public final class ReadWriteLock {
private int readingReaders = 0; // 实际正在读取的线程数量
private int waitingWriters = 0; // 正在等待写入的线程数量
private int writingWriters = 0; // (C)...实际正在写入的线程数量
private boolean preferWriter = true; // 写入优先的话,值为true
public synchronized void readLock() throws InterruptedException {
while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) {
wait();
}
readingReaders++; // (A)实际正在读取的线程数量加1
}
public synchronized void readUnlock() {
readingReaders--; // (A)实际正在读取的线程数量减1
preferWriter = true; //read处理后优先处理write
notifyAll();
}
public synchronized void writeLock() throws InterruptedException {
waitingWriters++; // (B)正在等待写入的线程数量加1
try {
while (readingReaders > 0 || writingWriters > 0) {
wait();
}
} finally {
waitingWriters--; // (B)正在等待写入的线程数量减1
}
writingWriters++; // (C)实际正在写入的线程数量加1
}
public synchronized void writeUnlock() {
writingWriters--; // (C)实际正在写入的线程数量减
preferWriter = false; //write处理后优先处理read
notifyAll();
}
}
总结
Read-Write Lock 模式适用于读取频率比写入频率高的场景。
Read-Write Lock Pattern将读取与写入分开处理,在读取数据之前必须获取用来读取的锁定,而写入的时候必须获取用来写入的锁定。因为读取时实例的状态不会改变,所以多个线程可以同时读取;但是,写入会改变实例的状态,所以当有一个线程写入的时候,其它线程既不能读取与不能写入。