一、concern conflict(同时发生以下两种操作是否会发生数据冲突)
1.read read false 可以并行化
2.write read true 需要串行化
3.read write true 需要串行化
4.write write true 需要串行化
二、多线程读写锁分离
读写锁
package com.dwz.concurrency2.chapter7; public class ReadWriteLock { private int readingReaders = 0;//正在读(当前有几个线程正在进行读的操作) private int waitingReaders = 0;//等待正在读(有几个线程想读,但是读不了) private int writingWriters = 0;//正在写(当前有几个线程正在进行写的操作) private int waitingWriters = 0;//等待正在写(有几个线程想写,但是锁被占用,写不了) private boolean perferWriter = true;//增加写的几率 public ReadWriteLock() { this(true); } public ReadWriteLock(boolean perferWriter) { this.perferWriter = perferWriter; } public synchronized void readLock() throws InterruptedException { this.waitingReaders++; try { while (writingWriters > 0 || (perferWriter && 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(); } }
共享数据
package com.dwz.concurrency2.chapter7; 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 this.doRead(); } finally { lock.readUnlock(); } } private char[] doRead() throws InterruptedException { char[] newBuf = new char[buffer.length]; for(int i = 0; i < buffer.length; i++) { newBuf[i] = buffer[i]; } Thread.sleep(50); return newBuf; } public void write(char c) throws InterruptedException { try { lock.writeLock(); this.doWrite(c); } finally { lock.writeUnlock(); } } private void doWrite(char c) throws InterruptedException { for(int i = 0; i < buffer.length; i++) { buffer[i] = c; Thread.sleep(10); } } }
读线程
package com.dwz.concurrency2.chapter7; public class ReaderWorker extends Thread { private final SharedData data; public ReaderWorker(SharedData data) { this.data = data; } @Override public void run() { try { while (true) { char[] readBuf = data.read(); System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readBuf)); } } catch (InterruptedException e) { e.printStackTrace(); } } }
写线程
package com.dwz.concurrency2.chapter7; import java.util.Random; public class WriterWorker extends Thread { private static final Random random = new Random(System.currentTimeMillis()); private final SharedData data; private final String filler; private int index = 0; public WriterWorker(SharedData 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(); } } private char nextChar() { char c = filler.charAt(index); index++; if(index > filler.length()) { index = 0; } return c; } }
测试
package com.dwz.concurrency2.chapter7; /** * ReadWriteLock design pattern * Reader-Writer design pattern */ public class ReaderWriterClient { public static void main(String[] args) { final SharedData data = new SharedData(10); new ReaderWorker(data).start(); new ReaderWorker(data).start(); new ReaderWorker(data).start(); new ReaderWorker(data).start(); new ReaderWorker(data).start(); new WriterWorker(data, "sdhkfhsdkfshdf").start(); new WriterWorker(data, "SDHKFHSDKFSHDF").start(); } }