仅模拟读写锁的实现原理,具体使用还是Java并发包中ReadWriteLock
读写锁的原理
读和读互不影响,读和写互斥,写和写互斥
代码实现
/**
* @Date: 2020/3/3 21:21
* @Description: 读写锁
*/
public class ReadWriteLock {
// 读线程
private int readingReaders = 0;
// 读等待线程
private int waitingReaders = 0;
// 写线程
private int writingWriters = 0;
// 写等待线程
private int waitingWriters = 0;
private boolean preferWrite = true;
public ReadWriteLock(){
this(true);
}
public ReadWriteLock(boolean perfer){
this.preferWrite = perfer;
}
// 读锁
public synchronized void readLock() throws InterruptedException{
this.waitingReaders++;
try{
while(writingWriters > 0 || (preferWrite && waitingWriters > 0)){
this.wait();
}
this.readingReaders++;
}finally {
this.waitingReaders--;
}
}
public synchronized void readUnlock(){
this.readingReaders--;
this.notifyAll();
}
// 写锁
public synchronized void writeLock() throws InterruptedException {
this.waitingWriters++;
try{
while (readingReaders > 0 || writingWriters > 0){
this.wait();
}
this.writingWriters++;
}finally {
this.waitingWriters--;
}
}
public synchronized void writeUnlock(){
this.writingWriters--;
this.notifyAll();
}
}
/**
* @Date: 2020/3/5 15:39
* @Description:
*/
public class ReaderWorker extends Thread {
private final ShareData data;
public ReaderWorker(ShareData data){
this.data = data;
}
@Override
public void run() {
try {
while(true){
char[] read = data.read();
System.out.println(Thread.currentThread().getName() +" reads " + String.valueOf(read));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
import java.util.Random;
/**
* @Date: 2020/3/5 15:14
* @Description:
*/
public class WriterWorker extends Thread {
private static final Random ran = new Random(System.currentTimeMillis());
private final ShareData data;
private final String filler;
private int index = 0;
public WriterWorker(ShareData data, String filler){
this.data = data;
this.filler = filler;
}
@Override
public void run() {
try {
while(true){
char c = nextChar();
System.out.println(Thread.currentThread().getName() + " write "+String.valueOf(c));
data.write(c);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private char nextChar(){
char c = filler.charAt(index);
index++;
if(index >= filler.length()){
index = 0;
}
return c;
}
}
/**
* @Date: 2020/3/5 14:15
* @Description:
*/
public class ShareData {
private final char[] buffer;
private final ReadWriteLock lock = new ReadWriteLock();
public ShareData(int size){
buffer = new char[size];
for (int i = 0; i < size; i++){
buffer[i] = '*';
}
}
public char[] read() throws InterruptedException {
try{
lock.readLock();
return doRead();
}finally {
lock.readUnlock();
}
}
public void write(char c) throws InterruptedException {
try{
lock.writeLock();
this.doWrite(c);
}finally {
lock.writeUnlock();
}
}
private void doWrite(char c) {
for(int i = 0; i < buffer.length; i++){
buffer[i] = c;
}
}
private char[] doRead() {
char[] newBuf = new char[buffer.length];
for(int i = 0; i < buffer.length; i++){
newBuf[i] = buffer[i];
}
return newBuf;
}
// private void slowly(int ms) {
// try {
// Thread.sleep(ms);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
}
测试类
/**
* @Date: 2020/3/5 15:44
* @Description:
*/
/**
* Read-Writer Lock design pattern
*/
public class ReadWriteLockClient {
public static void main(String[] args) {
final ShareData data = new ShareData(10);
new ReaderWorker(data).start();
new ReaderWorker(data).start();
new ReaderWorker(data).start();
new ReaderWorker(data).start();
new ReaderWorker(data).start();
new WriterWorker(data,"1234567890").start();
new WriterWorker(data,"1234567890").start();
new WriterWorker(data,"1234567890").start();
new WriterWorker(data,"1234567890").start();
new WriterWorker(data,"1234567890").start();
}
}