概述
大家一起讀沒問題谦趣,但是讀的時(shí)候不要寫哦疲吸。黑板上寫滿了板書,老師剛想擦前鹅,同學(xué)們說道:“老師摘悴,我們還沒看完呢,請(qǐng)先不要擦掉舰绘!”蹂喻。
示例程序
類一覽表
Main 測試程序行為的類
Data 可以讀寫的類
WriterThread 表示寫入線程的類
ReaderThread 表示讀取線程的類
ReadWriteLock 表示讀寫鎖的類
Main 類
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, "ABCDEF").start();
new WriterThread(data, "abcdef").start();
}
}
Data 類
Data類是可以執(zhí)行讀取(read)和寫入(write)操作的類捂寿。
buffer字段是實(shí)際的讀寫對(duì)象char的數(shù)組口四。
lock字段保存的是該模式的主角ReadWriteLock的實(shí)例。
public class Data {
private final char[] buffer;
private final ReadWriteLcok 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 = 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 類
import java.util.Random;
public class WriterThread extends Thread {
private static final Random random = new Random();
private final Data data;
private final String filter;
private int index = 0;
public WriterThread(Data data, String filter) {
this.data = data;
this.filter = filter;
}
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 = filter.charAt(index);
index++;
if(index >= filter.length()) {
index = 0;
}
return c;
}
}
ReadWriteLock 類
public final class ReadWriteLock {
private int readingReaders = 0; //(A)實(shí)際正在讀取中的線程數(shù)
private int waitingWriters = 0; //(B)正在等待寫入的線程個(gè)數(shù)
private int writingWriters = 0; //(C)實(shí)際正在寫入中的線程個(gè)數(shù)
private boolean preferWriter = true; /若寫入優(yōu)先秦陋,則為true
public synchronized void readLock() throws InterruptedException {
while( writingWriters > 0 || ( preferWriter && waitingWriters > 0)){
wait();
}
readingReaders++; //(A) 實(shí)際正在讀取的線程個(gè)數(shù)加1
}
public synchronized void readUnlock() {
readingReaders--; //(A)實(shí)際正在讀取的線程個(gè)數(shù)減1
preferWriter = true;
notifyAll();
}
public synchronized void writeLock() throws InterruptedException {
waitingWriters++; //(B)正在等待寫入的線程個(gè)數(shù)加1
try {
while ( readingReaders > 0 || writingWriters > 0) {
wait();
}
} finally {
waitingWriters--; //(B)正在等待寫入的線程個(gè)數(shù)減1
}
writingWriters++; //(C)實(shí)際在這寫入的線程個(gè)數(shù)加1
}
public synchronized void writeUnlock() {
writingWriters--;
preferWriter = false;
notifyAll();
}
}
守護(hù)條件確認(rèn)
ReadWriteLock類中readLock方法和writeLock方法都使用了Guarded Suspension模式蔓彩。
- readLock方法
守護(hù)條件是“沒有線程正在執(zhí)行寫入操作”。 - writeLock方法
守護(hù)條件是“沒有線程正在執(zhí)行讀取操作或?qū)懭氩僮鳌薄?/li>
Read-Write Lock 模式中的登場角色
- Reader(讀者)
Reader角色對(duì)SharedResource角色執(zhí)行read操作驳概。在示例程序中赤嚼,由ReaderThread類扮演。 - Writer(寫者)
Writer角色對(duì)SharedResource角色執(zhí)行write操作顺又。在示例程序中探膊,由WriterThread類扮演。 - SharedResource(共享資源)
SharedResource角色表示的是Reader角色和Writer角色二者共享的資源待榔。在示例程序中逞壁,由Data類扮演。 - ReadWriteLock(讀寫鎖)
ReadWriteLock角色提供了read操作和write操作時(shí)所需的鎖锐锣。即實(shí)現(xiàn)read操作時(shí)所需的readLock和readUnlock腌闯,以及實(shí)現(xiàn)write操作時(shí)所需要的writeLock和writeUnlock。在示例程序中雕憔,由ReadWriteLock類扮演姿骏。