读写锁适用读多写少的场景,读写锁需求必须知足条件:dom
1.一个线程对共享数据read时,同时容许另一个线程能够并行read操做ide
2.一个线程对共享数据read时,不容许同时另一个线程进行write操做测试
3.一个线程对共享数据write时,不容许同时另一个线程进行write操做this
第一步:线程
建立一个读写锁,优先写操做进行,为了在读多写少的场景下,能更多执行写操做。code
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 { try { this.waitingReaders++; 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 { try { this.waitingWriters++; while(writingWriters > 0 || readingReaders > 0) { this.wait(); } this.writingWriters++; }finally { this.waitingWriters--; } } public synchronized void writeUnLock() { this.writingWriters--; this.notifyAll(); } }
第二步:对象
建立一个共享数据对象,用于读写操做get
public class ShareData { private final char[] buffer; private final ReadWriteLock lock = new ReadWriteLock(); public ShareData(int size) { this.buffer = new char[size]; for (int i = 0; i < buffer.length; i++) { buffer[i] = '*'; } } public char[] read() throws InterruptedException { try{ lock.readLock(); return this.doRead(); }finally { lock.readUnLock(); } } public void write(char c) throws InterruptedException { try{ lock.writeLock(); this.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[] newBuf = new char[buffer.length]; for (int i = 0; i < buffer.length; i++) { newBuf[i] = buffer[i]; } slowly(500); return newBuf; } private void slowly(int ms) { try { Thread.sleep(ms); } catch (InterruptedException e) { e.printStackTrace(); } } }
第三步:it
建立一个写线程,对共享对象进行写操做io
public class WriterWorker extends Thread{ private static final Random random = new Random(System.currentTimeMillis()); private final ShareData data; private final String filler; private int index; public WriterWorker(ShareData data, String filler) { this.data = data; this.filler = filler; } @Override public void run() { try { while(true) { char c = nextChar(); data.write(c); Thread.sleep(random.nextInt(1000)); } } catch (InterruptedException e) { e.printStackTrace(); } } public char nextChar() { char c = filler.charAt(index); index++; if(index >= filler.length()) { index = 0; } return c; } }
第四步:
建立一个读线程,对共享对象进行读操做,并输出读数据内容
ublic class ReaderWorker extends Thread{ private final ShareData data; public ReaderWorker(ShareData data) { this.data = data; } @Override public void run() { try { while (true) { char[] readBuffer = data.read(); System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readBuffer)); } } catch (InterruptedException e) { e.printStackTrace(); } } }
第五步:
建立一个读多写少的测试类
public class ReadWriteLockClient { public static void main(String[] args) { final ShareData shareData = new ShareData(10); new ReaderWorker(shareData).start(); new ReaderWorker(shareData).start(); new ReaderWorker(shareData).start(); new ReaderWorker(shareData).start(); new ReaderWorker(shareData).start(); new WriterWorker(shareData, "ddjifjsidjfisd").start(); new WriterWorker(shareData, "DDJIFJSIDJFISD").start(); } }
第六步:
查看打印结果
Thread-0 reads ********** Thread-1 reads ********** Thread-2 reads ********** Thread-4 reads ********** Thread-3 reads ********** Thread-0 reads DDDDDDDDDD Thread-1 reads DDDDDDDDDD Thread-2 reads DDDDDDDDDD Thread-4 reads DDDDDDDDDD Thread-3 reads DDDDDDDDDD Thread-3 reads dddddddddd Thread-1 reads dddddddddd Thread-0 reads dddddddddd Thread-2 reads dddddddddd Thread-4 reads dddddddddd Thread-4 reads JJJJJJJJJJ Thread-3 reads JJJJJJJJJJ Thread-0 reads JJJJJJJJJJ Thread-1 reads JJJJJJJJJJ Thread-2 reads JJJJJJJJJJ Thread-2 reads IIIIIIIIII Thread-3 reads IIIIIIIIII Thread-1 reads IIIIIIIIII Thread-0 reads IIIIIIIIII Thread-4 reads IIIIIIIIII