在进行读写操作的时候,读是可以并发的,但是写是不可以的,只能串行
READER | WRITER | |
READER | YES | NO |
WRITER | NO | NO |
这种方式是把读操作放开,提高线程执行速度,把写操作添加同步代码块,保证顺序性原子性。
public class ReadWriteLock {
private int readings = 0;
private int waitingReaders = 0;
private int writings = 0;
private int waitWriters = 0;
private boolean preform;
public ReadWriteLock() {
this(true);
}
public ReadWriteLock(boolean preform) {
this.preform = preform;
}
public synchronized void readLock() throws InterruptedException {
waitingReaders++;
try {
while (writings > 0 && (preform && waitWriters > 1)) {
this.wait();
}
readings++;
} finally {
waitingReaders--;
}
}
public synchronized void readUnlock() {
notifyAll();
readings--;
}
public synchronized void writeLock() throws InterruptedException {
waitWriters++;
try {
while (writings > 0 || readings > 0) {//如果是正在写或者正在读,就不可以进行写的操作
wait();
}
writings++;
} finally {
waitWriters--;
}
}
public synchronized void writeUnlock() {
notifyAll();
writings--;
}
}
public class SharedResource {
private final ReadWriteLock lock = new ReadWriteLock();
private final char[] buffer ;
public SharedResource(int size){
buffer = new char[size];
for(int i = 0 ; i < size ; i++){
buffer[i] = '*';
}
}
public char[] read() throws InterruptedException{
try {
lock.readLock();
return doRead();
} finally {
lock.readUnlock();
}
}
private char[] doRead() {
char[] bufferCopy = new char[buffer.length];
for(int i = 0 ,length = buffer.length; i < length; i++){
bufferCopy[i] = buffer[i];
}
return bufferCopy;
}
public void write(char c) throws InterruptedException {
try {
lock.writeLock();
doWrite(c);
}finally {
lock.writeUnlock();
}
}
private void doWrite(char c) {
for(int i = 0 ,length = buffer.length; i < length ; i ++){
buffer[i] = c;
}
System.out.println(Thread.currentThread().getName() + " write " + String.valueOf(buffer));
}
public class Reader extends Thread {
private SharedResource resource;
public Reader(SharedResource resource) {
this.resource = resource;
}
@Override
public void run() {
try {
while (true) {
System.out.println(getName() + " read " + String.valueOf(resource.read()));
Thread.sleep(45);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Writer extends Thread {
private SharedResource resource;
private String filler;
private Random random = new Random(System.currentTimeMillis());
public Writer(SharedResource resource, String filler) {
this.resource = resource;
this.filler = filler;
}
@Override
public void run() {
try {
while (true) {
resource.write(nextChar());
Thread.sleep(50);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private char nextChar() {
int index = random.nextInt(filler.length());
return filler.charAt(index);
}
}
public class ReaderWriterClient {
public static void main(String[] args){
SharedResource r = new SharedResource(10);
new Reader(r).start();
new Reader(r).start();
new Reader(r).start();
new Reader(r).start();
new Reader(r).start();
new Writer(r,"qwertyuiopasdf").start();
new Writer(r,"QWERTYUIOPASDF").start();
}
}