二.多线程设计模式篇-2.3 读写锁分离设计模式
多个线程同时读一个资源类是没有任何问题的,所以为了满足在并发的情况下,读取共享资源应该是可以同时进行的;但是,如果一个线程想要去写共享资源,就不应该再有其他线程可以对该共享资源进行读或者是写操作了。
1.读写锁
public class ReadWriteLock {
private int readingReaders = 0;
private int waitingReaders = 0;
private int writingWriters = 0;
private int waitingWriters = 0;
private boolean preferWriter = true;
public ReadWriteLock() {
this(true);
}
public ReadWriteLock(boolean preferWriter) {
this.preferWriter = preferWriter;
}
public synchronized void readLock() throws InterruptedException {
this.waitingReaders++;
try {
while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) {
this.wait();
}
this.readingReaders++;
} finally {
this.waitingReaders--;
}
}
public synchronized void readUnlock() {
this.readingReaders--;
this.notifyAll();
}
public synchronized void writeLock() throws InterruptedException {
this.waitingWriters++;
try {
while (readingReaders > 0 || writingWriters > 0) {
this.wait();
}
this.writingWriters++;
} finally {
this.waitingWriters--;
}
}
public synchronized void writeUnlock() {
this.writingWriters--;
this.notifyAll();
}
}
2.共享数据
public class SharedData {
private final char[] buffer;
private final ReadWriteLock lock = new ReadWriteLock();
public SharedData(int size) {
this.buffer = new char[size];
for (int i = 0; i < size; i++){
this.buffer[i] = '*';
}
}
public char[] read() throws InterruptedException {
try {
lock.readLock();
return doRead();
} finally {
lock.readUnlock();
}
}
public void write(char c) throws InterruptedException {
try{
lock.writeLock();
doWrite(c);
}finally {
lock.writeUnlock();
}
}
private void doWrite(char c) {
for (int i = 0; i < buffer.length; i++) {
buffer[i] = c;
slowly(10);
}
}
private char[] doRead() {
char[] newBuffer = new char[this.buffer.length];
for (int i = 0; i < newBuffer.length; i++){
newBuffer[i] = this.buffer[i];
}
slowly(50);
return newBuffer;
}
private void slowly(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
}
}
}
3.读工作线程
public class ReadWorker extends Thread {
private final SharedData sharedData;
public ReadWorker(SharedData sharedData) {
this.sharedData = sharedData;
}
@Override
public void run() {
try {
while (true){
char[] buffer = this.sharedData.read();
System.out.println(Thread.currentThread().getName() + " reader: " + String.valueOf(buffer));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
4.写工作线程
public class WriterWorker extends Thread {
private final String filler;
private final SharedData sharedData;
private int index = 0;
private static final Random random = new Random(System.currentTimeMillis());
public WriterWorker(String filler, SharedData sharedData) {
this.filler = filler;
this.sharedData = sharedData;
}
@Override
public void run() {
while(true){
char c = nextChar();
try {
sharedData.write(c);
Thread.sleep(random.nextInt());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private char nextChar() {
char c = filler.charAt(index);
index++;
if (index >= filler.length()){
index = 0;
}
return c;
}
}
5.客户端
public class ReadWriteLockClient {
public static void main(String[] args) {
SharedData sharedData = new SharedData(10);
new ReadWorker(sharedData).start();
new ReadWorker(sharedData).start();
new ReadWorker(sharedData).start();
new ReadWorker(sharedData).start();
new ReadWorker(sharedData).start();
new WriterWorker("qweasdzxc", sharedData).start();
new WriterWorker("QWEASDZXC", sharedData).start();
}
}
还没有评论,来说两句吧...