Read-Write Lock模式

一、定義
Read-Write Lock Pattern將讀取與寫(xiě)入分開(kāi)處理,在讀取數(shù)據(jù)之前必須獲取用來(lái)讀取的鎖定,而寫(xiě)入的時(shí)候必須獲取用來(lái)寫(xiě)入的鎖定。因?yàn)樽x取時(shí)實(shí)例的狀態(tài)不會(huì)改變,所以多個(gè)線程可以同時(shí)讀取;但是,寫(xiě)入會(huì)改變實(shí)例的狀態(tài),所以當(dāng)有一個(gè)線程寫(xiě)入的時(shí)候,其它線程既不能讀取與不能寫(xiě)入。

二、模式案例

Data類(lèi):
數(shù)據(jù)類(lèi)可以被多個(gè)線程同時(shí)訪問(wèn)。

public class Data {
    private final char[] buffer;
    private final ReadWriteLock lock = new ReadWriteLock();
    public Data(int size) {
        this.buffer = new char[size];
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = '*';
        }
    }
    public char[] read() throws InterruptedException {
        lock.readLock();
        try {
            return doRead();
        } finally {
            lock.readUnlock();
        }
    }
    public void write(char c) throws InterruptedException {
        lock.writeLock();
        try {
            doWrite(c);
        } finally {
            lock.writeUnlock();
        }
    }
    private char[] doRead() {
        char[] newbuf = new char[buffer.length];
        for (int i = 0; i < buffer.length; i++) {
            newbuf[i] = buffer[i];
        }
        slowly();
        return newbuf;
    }
    private void doWrite(char c) {
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = c;
            slowly();
        }
    }
    private void slowly() {
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
        }
    }
}

WriterThread類(lèi):

public class WriterThread extends Thread {
    private static final Random random = new Random();
    private final Data data;
    private final String filler;
    private int index = 0;
    public WriterThread(Data data, String filler) {
        this.data = data;
        this.filler = filler;
    }
    public void run() {
        try {
            while (true) {
                char c = nextchar();
                data.write(c);
                Thread.sleep(random.nextInt(3000));
            }
        } catch (InterruptedException e) {
        }
    }
    private char nextchar() {
        char c = filler.charAt(index);
        index++;
        if (index >= filler.length()) {
            index = 0;
        }
        return c;
    }
}

ReaderThread類(lèi):

public class ReaderThread extends Thread {
    private final Data data;
    public ReaderThread(Data data) {
        this.data = data;
    }
    public void run() {
        try {
            while (true) {
                char[] readbuf = data.read();
                System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readbuf));
            }
        } catch (InterruptedException e) {
        }
    }
}

ReadWriteLock類(lèi):
讀寫(xiě)鎖需要防止以下兩類(lèi)沖突:

  • “讀取”和“寫(xiě)入”的沖突(read-write conflict)
  • “寫(xiě)入”和“寫(xiě)入”的沖突(write-write conflict)
  • 注意:“讀取”和“讀取”之間不會(huì)沖突*
public final class ReadWriteLock {
    private int readingReaders = 0;        //正在讀取線程的數(shù)量 
    private int writingWriters = 0;     //正在寫(xiě)入線程的數(shù)量
    public synchronized void readLock() throws InterruptedException {
        while (writingWriters > 0 ) {
            wait();
        }
        readingReaders++;                      
    }
    public synchronized void readUnlock() {
        readingReaders--;   
        notifyAll();
    }
    public synchronized void writeLock() throws InterruptedException {
        while (readingReaders > 0 || writingWriters > 0) {
            wait();
        }
        writingWriters++;                       
    }
    public synchronized void writeUnlock() {
        writingWriters--;     
        notifyAll();
    }
}

執(zhí)行:

public class Main {
    public static void main(String[] args) {
        Data data = new Data(10);
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new ReaderThread(data).start();
        new WriterThread(data, "ABCDEFGHIJKLMNOPQRSTUVWXYZ").start();
        new WriterThread(data, "abcdefghijklmnopqrstuvwxyz").start();
    }
}

三、模式講解
Read-Write Lock模式的角色如下:

  • Reader(讀取者)參與者
    Reader參與者會(huì)對(duì)SharedResource進(jìn)行讀。
  • Writer(寫(xiě)入者)參與者
    Writer參與者會(huì)對(duì)SharedResource進(jìn)行寫(xiě)。
  • SharedResource(共享資源)參與者
    SharedResource代表Reader和Writer所共享的資源對(duì)象,SharedResource提供不改變內(nèi)部狀態(tài)的read操作,以及會(huì)改變內(nèi)部狀態(tài)的write操作。
  • ReadWriteLock(讀寫(xiě)鎖)參與者
    ReadWriteLock提供了對(duì)SharedResource參與者進(jìn)行read操作和write操作時(shí)需要的鎖定。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容