Write simple read-write locks plus

Foreword

Is what I do not lock the BB, you first achieve a simple read-write locks himself not Miya before learning JUC.

text

Read-Write Lock
* 读写锁
**/
public class ReadWriteLock {
private int readingReaders = 0; //正在读的线程数
private int waitingReaders = 0; //正在等待锁的读线程数
private int writingWriters = 0; //正在写的线程数
private int waitingWriters = 0; //正在等待锁的写线程数
private boolean readerFirst = true; //写者优先
/**
* 无参构造,默认读者优先
*/
public ReadWriteLock() {
this(true);
}

public ReadWriteLock(boolean preferReader) {
this.readerFirst = preferReader;
}

/**
* 读锁
*/
public synchronized void readLock() throws InterruptedException {
//有读线程需要来获取锁,读等待线程数量加1.
this.waitingReaders++;
try {
//如果有读线程正在写,则阻塞。不阻塞读,到达读读无锁的目的。
while (writingWriters > 0) {
this.wait();
}
//没有写线程正在写,则可以进行读了,并将正在读线程数量++。
this.readingReaders++;
}finally {
//等待读线程数量--
this.waitingReaders--;
}
}

/**
* 读解锁
*/
public synchronized void readUnlock() {
//读完成后,正在读线程数量--
this.readingReaders--;
//唤醒所有被阻塞的线程,能被读解锁唤醒的阻塞线程一定是写线程。
this.notifyAll();
}

/**
* 写锁
*/
public synchronized void writeLock() throws InterruptedException {
//有写线程需要来获取锁,写等待线程数量加1.
this.waitingWriters++;
try {
//如果有正在写的线程 或 有正在读的线程 或 有等待的读线程(读者优先),则当前写线程阻塞。
while (writingWriters > 0 || readingReaders > 0 || (readerFirst && waitingReaders > 0)) {
this.wait();
}
//如果无,则可以开始进行写,正在写线程数量++
this.writingWriters++;
} finally {
//等待读线程数量--
this.waitingWriters--;
}
}

/**
* 写解锁
*/
public synchronized void writeUnlock() {
//写完成后,正在写线程数量--
this.writingWriters--;
//唤醒所有被阻塞的线程,读写皆有可能。
this.notifyAll();
}

public int getWaitingWriters(){
return waitingWriters;
}

public int getWaitingReaders(){
return waitingReaders;
}
}
复制代码

Above is determined by the code in the statistical parameters and blocking mode, implements a simple "write", "write" mutually exclusive lock, but the "read" not mutually exclusive.

If there are waiting to be read (before someone is writing, blocking lived) before writing thread to acquire the lock, then the writing thread is blocked waiting, give priority thread is waiting to be read.

Note: If you want to change the priority for the writers, you can change the code, increasing the flag, or a flag multiplexed manner, and conditions can change the cycle in judgment.

Share resource

/*
* 共享资源
**/
public class SharedData {

private String value;

private final ReadWriteLock lock = new ReadWriteLock();

public SharedData() {
value = "";
}

public String read() throws InterruptedException {
try {
lock.readLock();
System.out.println("正在写等待的线程数量 :"+lock.getWaitingWriters());
System.out.println("正在读等待的线程数量 :"+lock.getWaitingReaders());
System.out.println(Thread.currentThread().getName() + " 读到了: " + this.value);
System.out.println("------------------------------------------------");
sleep(100);
return this.value;
} finally {
lock.readUnlock();
}
}

public void write(String s) throws InterruptedException {
try {
lock.writeLock();
System.out.println("正在写等待的线程数量:"+lock.getWaitingReaders());
System.out.println("正在读等待的线程数量 :"+lock.getWaitingReaders());
System.out.println(Thread.currentThread().getName() + " 写了: " + s);
System.out.println("------------------------------------------------");
sleep(200);
this.value = s;
} finally {
lock.writeUnlock();
}
}

private void sleep(int ms) throws InterruptedException {
Thread.sleep(ms);
}
}
复制代码

Analog worker threads to read and write

Reading the worker thread
* 模拟读线程
*/
public class ReaderWorker extends Thread {

private static final Random random = new Random(System.currentTimeMillis());

//共享资源
private final SharedData data;

public ReaderWorker(SharedData data) {
this.data = data;
}

@Override
public void run() {
try {
while (true) {
String s = data.read();
sleep(random.nextInt(1000));
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+"被中断了~");
return;
}
}
}
复制代码
Write worker
 * 模拟写线程
*/
public class WriterWorker extends Thread {

private static final Random random = new Random(System.currentTimeMillis());

private final SharedData data;

private String s;

public WriterWorker(SharedData data, String s) {
this.data = data;
this.s = s;
}

@Override
public void run() {
try {
while (true) {
data.write(s);
Thread.sleep(random.nextInt(1000));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
复制代码
International practice the main thread psvm
 * 读写锁test
*/
public class ReadWritLockClient {
public static void main(String[] args) {
final SharedData sharedData = new SharedData();
new ReaderWorker(sharedData).start();
new ReaderWorker(sharedData).start();
new WriterWorker(sharedData, "ABC").start();
new WriterWorker(sharedData, "DEF").start();
new WriterWorker(sharedData, "GHI").start();
new WriterWorker(sharedData, "JKL").start();
new WriterWorker(sharedData, "LMN").start();
}
}
复制代码

Analog several threads to read and write shared resource contention

verification

It will not happen, "read", "write" of bin ~

As used herein, mdnice typesetting

Guess you like

Origin juejin.im/post/5e83058651882573be11b4e9