Lock:
public interface Lock{ void lock() throws InterruptedException; void unlock(); }
Locks:
public interface ReadWriteLock { Lock readLock(); Lock writeLock(); int getWritingWriters(); //获取当前有多少个线程正在执行写操作 int getReadingReaders(); //获取当前有多少个线程政治等待获取ReadingReaders int getWaitingWriters(); //获取当前有多少个线程正在等待获取写入锁 static ReadWriteLock readWriteLock(){ return new ReadWriteLockImpl(); } static ReadWriteLock readWriteLock(boolean preferWriter){ return new ReadWriteLockImpl(preferWriter); } } class ReadWriteLockImpl implements ReadWriteLock{ private final Object MUTEX = new Object(); private int writingWriters = 0; //当前有多少个线程正在写入 private int waitingWriters = 0; //当前有多少个线程正在等待写入 private int readingReaders = 0; //当前有多少个线程正在读 private boolean preferWriter; public ReadWriteLockImpl() { this(true); } public ReadWriteLockImpl(boolean preferWriter){ this.preferWriter=preferWriter; } @Override public Lock readLock() { return new ReadLock(this); } @Override public Lock writeLock() { return new WriteLock(this); } void incrementWritingWriters() { this.writingWriters++; } void incrementWaitingWriters(){ this.waitingWriters++; } void incrementReadingReaders(){ this.readingReaders++; } void decrementWritingWriters() { this.writingWriters--; } void decrementWaitingWriters(){ this.waitingWriters--; } void decrementtReadingReaders(){ this.readingReaders--; } @Override public int getWritingWriters() { return this.writingWriters; } @Override public int getReadingReaders() { return readingReaders; } @Override public int getWaitingWriters() { return waitingWriters; } Object getMutex(){ return this.MUTEX; } public boolean getPreferWriter() { return preferWriter; } void changePrefer(boolean preferWriter){ this.preferWriter=preferWriter; } } class ReadLock implements Lock{ private final ReadWriteLockImpl readWriteLock; public ReadLock(ReadWriteLockImpl readWriteLock) { this.readWriteLock = readWriteLock; } @Override public void lock() throws InterruptedException { synchronized (readWriteLock.getMutex()){ /* 对这段逻辑的分析: 1.如果你正在写的大于一,我的确应该等待 2.如果你偏好于写,同时等待的多于一,那么: 我读这边应该等待 */ while(readWriteLock.getWritingWriters()>0|| (readWriteLock.getPreferWriter()&& readWriteLock.getWaitingWriters()>0)){ readWriteLock.getMutex().wait(); } readWriteLock.incrementReadingReaders(); } } @Override public void unlock() { synchronized (readWriteLock.getMutex()) { /* 将preferWriter设置为true,可以使得writer获得更多的机会 */ readWriteLock.decrementtReadingReaders(); readWriteLock.changePrefer(true); readWriteLock.getMutex().notifyAll(); } } } class WriteLock implements Lock { private final ReadWriteLockImpl readWriteLock; public WriteLock(ReadWriteLockImpl readWriteLock) { this.readWriteLock = readWriteLock; } @Override public void lock() throws InterruptedException { synchronized (readWriteLock.getMutex()) { try{ readWriteLock.incrementWaitingWriters(); while(readWriteLock.getReadingReaders()>0|| readWriteLock.getWritingWriters()>0){ readWriteLock.getMutex().wait(); } }finally { this.readWriteLock.decrementWaitingWriters(); } readWriteLock.incrementWritingWriters(); } } @Override public void unlock() { synchronized (readWriteLock.getMutex()) { readWriteLock.decrementWritingWriters(); readWriteLock.changePrefer(false); readWriteLock.getMutex().notifyAll(); } } }
测试代码:
import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args){ ReadWriteLockTest.test(); } } class ShareData{ private final List<Character> container = new ArrayList<>(); private final ReadWriteLock readWriteLock = ReadWriteLock.readWriteLock(); private final Lock readLock = readWriteLock.readLock(); private final Lock writeLock = readWriteLock.writeLock(); private final int length; public ShareData(int length) { this.length = length; for (int i = 0; i < length; i++) { container.add(i,'c'); } } public char[] read() throws InterruptedException { try{ readLock.lock(); char[] newBuffer = new char[length]; for (int i = 0; i < length; i++) { newBuffer[i]=container.get(i); } slowly(); return newBuffer; }finally { readLock.unlock(); } } public void write(char c) throws InterruptedException{ try{ writeLock.lock(); for (int i = 0; i < length; i++) { this.container.add(i, c); } slowly(); }finally { writeLock.unlock(); } } private void slowly(){ try{ TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } class ReadWriteLockTest{ private final static String text = "Thisistheexampleforreadwritelock"; public static void test(){ final ShareData shareData = new ShareData(50); for (int i = 0; i < 2; i++) { new Thread(()->{ for (int index = 0; index < text.length(); index++) { try{ char c = text.charAt(index); shareData.write(c); System.out.println(Thread.currentThread()+" write "+c); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } for (int i = 0; i < 10; i++) { new Thread(()->{ while (true) { try{ System.out.println(Thread.currentThread()+" read "+new String(shareData.read())); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } } }