簡単な読み書きロックを書くプラス

序文

あなたが最初JUCを学ぶ前に、自分自身ではない宮簡単な読み書きロックを達成するため、私はBBをロックしていないものです。

テキスト

読み書きロック
* 读写锁
**/
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;
}
}
复制代码

上記は、統計パラメータのコードとブロックモード、実装の単純な「書き込み」、「書き込み」、相互排他ロックによって決定されますが、相互に排他的ではなく、「読み」。

(誰かが書き込みされる前に住んでいたブロッキング)ロックを取得するためのスレッドを書き込む前に読まれるのを待っているがある場合、書き込みスレッドが待機、所与の優先度のスレッドを読まれるのを待っているブロックされています。

注:あなたは作家のための優先順位を変更したい場合は、コードを変更することができ、フラグを増やす、またはフラグがやり方を多重化し、条件が判断で、サイクルを変更することができます。

リソースを共有します

/*
* 共享资源
**/
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);
}
}
复制代码

アナログワーカースレッドを読み書きします

ワーカースレッドを読みます
* 模拟读线程
*/
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;
}
}
}
复制代码
ライトワーカー
 * 模拟写线程
*/
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();
}
}
}
复制代码
メインスレッド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();
}
}
复制代码

共有リソースの競合を読み書きするアナログ複数のスレッド

検証

〜、「読み」、ビンの「書き込み」を発生しません

本明細書で使用される場合、mdnice組版

おすすめ

転載: juejin.im/post/5e83058651882573be11b4e9