Read Write Lock 模式
Read Write Lock 模式就是将内容的读取和写入分开进行处理。
因为数据的互斥需要牺牲性能,读的时候可以互不影响,但是读的时候禁止写。
实际案例
类信息概览:
类名 | 说明 |
---|---|
Main.java | 方法的总入口 |
WriterThread.java | 写线程 |
MyReadWriteLock.java | 自定义读写锁 |
ReadWriteLock.java | 读写锁 |
ReaderThread.java | 读线程 |
Data.java | 数据对象 |
定义
- WriterThread.java
package com.github.houbb.thread.learn.easy.learn.rwlock;
import com.github.houbb.thread.learn.easy.learn.CharUtil;
import com.github.houbb.thread.learn.easy.learn.ThreadUtil;
public class WriterThread extends Thread {
private Data data;
public WriterThread(Data data) {
super("WriterThread");
this.data = data;
}
@Override
public void run() {
while(true) {
char c = CharUtil.nextChar();
try {
System.out.println(Thread.currentThread().getName() + " writes " + c);
data.write(c);
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadUtil.sleepRandom();
}
}
}
- MyReadWriteLock.java
package com.github.houbb.thread.learn.easy.learn.rwlock;
/**
* 读写冲突
* 写写冲突
*/
public class MyReadWriteLock implements ReadWriteLock {
private int readingReaders = 0; //正在读的
private int waitingWriters = 0; //等待写的
private int writingWriters = 0; //正在写的
private boolean preferWriter = true; //写优先
@Override
public synchronized void readLock() throws InterruptedException {
while(writingWriters > 0
|| (preferWriter && waitingWriters > 0)) {
wait();
}
readingReaders++; //读+1
}
@Override
public synchronized void readUnLock() {
if(readingReaders > 0) {
readingReaders--;
}
preferWriter = true; //优先写
notifyAll();
}
@Override
public synchronized void writeLock() throws InterruptedException {
waitingWriters++;
try {
while(writingWriters > 0
|| readingReaders > 0) {
wait();
}
} finally {
waitingWriters--;
}
writingWriters++;
}
@Override
public synchronized void writeUnLock() {
writingWriters--;
preferWriter = false;
notifyAll();
}
}
- ReadWriteLock.java
package com.github.houbb.thread.learn.easy.learn.rwlock;
public interface ReadWriteLock {
void readLock() throws InterruptedException;
void readUnLock() throws InterruptedException;
void writeLock() throws InterruptedException;
void writeUnLock() throws InterruptedException;
}
- ReaderThread.java
package com.github.houbb.thread.learn.easy.learn.rwlock;
import com.github.houbb.thread.learn.easy.learn.ThreadUtil;
public class ReaderThread extends Thread {
private Data data;
public ReaderThread(Data data) {
this.data = data;
}
@Override
public void run() {
while(true) {
try {
char[] chars = data.read();
System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(chars));
ThreadUtil.sleepRandom();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- Data.java
package com.github.houbb.thread.learn.easy.learn.rwlock;
import com.github.houbb.thread.learn.easy.learn.ThreadUtil;
import java.util.Arrays;
public class Data {
private final int size;
private char[] buffer;
private final ReadWriteLock readWriteLock = new MyReadWriteLock();
public Data(int size) {
this.size = size;
buffer = new char[size];
initBuffer();
}
private void initBuffer() {
Arrays.fill(buffer, '*');
}
public char[] read() throws InterruptedException {
readWriteLock.readLock();
try {
//copy current value
char[] result = new char[size];
System.arraycopy(buffer, 0, result, 0, size);
ThreadUtil.sleep(50);
return result;
} finally {
readWriteLock.readUnLock();
}
}
public void write(char c) throws InterruptedException {
readWriteLock.writeLock();
//do write
try {
Arrays.fill(buffer, c);
ThreadUtil.sleep(50);
} finally {
readWriteLock.writeUnLock();
}
}
}
测试
- Main.java
package com.github.houbb.thread.learn.easy.learn.rwlock;
public class Main {
public static void main(String[] args) {
Data data = new Data(10);
new ReaderThread(data).start();
new ReaderThread(data).start();
new WriterThread(data).start();
}
}
- 测试结果
实现方式
UML & Code
UML
Code
代码地址