多线程读写锁分离设计模式

一、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();
    }
}
原文地址:https://www.cnblogs.com/zheaven/p/12120886.html