Java多線程基礎(八)——Read-Write Lock模式

1、定義

Read-Write Lock Pattern將讀取與寫入分開處理,在讀取數據以前必須獲取用來讀取的鎖定,而寫入的時候必須獲取用來寫入的鎖定。由於讀取時實例的狀態不會改變,因此多個線程能夠同時讀取;可是,寫入會改變實例的狀態,因此當有一個線程寫入的時候,其它線程既不能讀取與不能寫入。dom

2、模式案例

Data類:
數據類能夠被多個線程同時訪問。this

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類:spa

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類:線程

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類:
讀寫鎖須要防止如下兩類衝突:code

  • 「讀取」和「寫入」的衝突(read-write conflict)
  • 「寫入」和「寫入」的衝突(write-write conflict)
  • 注意:「讀取」和「讀取」之間不會衝突*
public final class ReadWriteLock {
    private int readingReaders = 0;        //正在讀取線程的數量 
    private int writingWriters = 0;     //正在寫入線程的數量
    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();
    }
}

執行:對象

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();
    }
}

3、模式講解

Read-Write Lock模式的角色以下:資源

  • Reader(讀取者)參與者

Reader參與者會對SharedResource進行讀。rem

  • Writer(寫入者)參與者

Writer參與者會對SharedResource進行寫。get

  • SharedResource(共享資源)參與者

SharedResource表明Reader和Writer所共享的資源對象,SharedResource提供不改變內部狀態的read操做,以及會改變內部狀態的write操做。it

  • ReadWriteLock(讀寫鎖)參與者

ReadWriteLock提供了對SharedResource參與者進行read操做和write操做時須要的鎖定。

相關文章
相關標籤/搜索