Read-Write Lock Pattern將讀取與寫入分開處理,在讀取數據以前必須獲取用來讀取的鎖定,而寫入的時候必須獲取用來寫入的鎖定。由於讀取時實例的狀態不會改變,因此多個線程能夠同時讀取;可是,寫入會改變實例的狀態,因此當有一個線程寫入的時候,其它線程既不能讀取與不能寫入。dom
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
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(); } }
Read-Write Lock模式的角色以下:資源
Reader參與者會對SharedResource進行讀。rem
Writer參與者會對SharedResource進行寫。get
SharedResource表明Reader和Writer所共享的資源對象,SharedResource提供不改變內部狀態的read操做,以及會改變內部狀態的write操做。it
ReadWriteLock提供了對SharedResource參與者進行read操做和write操做時須要的鎖定。