美文网首页
读写锁分离设计

读写锁分离设计

作者: 程序设计法师 | 来源:发表于2019-01-02 15:38 被阅读0次
public interface Lock {
    //获取显示锁,没有获得锁的线程将被阻塞
    void lock() throws InterruptedException;
    //释放获取的锁
    void unlock();
}
public interface ReadWriteLock {
    //创建reader锁
    Lock readLock();
    //创建write锁
    Lock writeLock();
    //获取当前有多少线程正在执行写操作
    int getWritingWriters();
    //获取当前有多少个线程正在等待获取写入锁
    int getWaitingWriters();
    //获取当前有多少个线程正在等待获取reader锁
    int getReadingReaders();
    //工厂方法,创建ReaderWriteLock
    static ReadWriteLock readWriteLock(){
        return new ReadWriteLockImpl();
    }
    //工厂方法,创建ReadWriteLock,并且传入preferWriter
     static ReadWriteLock readWriteLock(boolean preferWriter)
    {
        return new ReadWriteLockImpl(preferWriter);
    }
}
public class ReadWriteLockImpl implements ReadWriteLock {
    //定义对象锁
    private final Object MUTEX=new Object();
    //当前有多少个线程正在写入
    private int writingWriters=0;
    //当前有多少个线程正在等待写入
    private int waitingWriters=0;
    //当前有多少个线程正在read
    private int readingReaders=0;
    //read和write的偏好设置
    private boolean preferWriter;
    //默认情况下perferWriter为true
    public ReadWriteLockImpl() {
        this(true);
    }

    public ReadWriteLockImpl(boolean preferWriter) {
        this.preferWriter = preferWriter;
    }

    //创建read lock
    @Override
    public Lock readLock() {
        return new ReadLock(this);
    }

    @Override
    public Lock writeLock() {
        return new WriteLock(this);
    }
    //使写线程的数量增加
    public void incrementWritingWriters(){
        this.writingWriters++;
    }
    //使写线程的数量减少
    public void decrementWritingWriters(){
        this.writingWriters--;
    }
    //获取当前有多少个线程正在进行写操作
    @Override
    public int getWritingWriters() {
        return writingWriters;
    }
    //使等待写入的线程的数量增加
    public void incrementWaitingWriters(){
        this.waitingWriters++;
    }
    //使等待获取写入锁的数量减少
    public void decrementWaitingWriters(){
        this.waitingWriters--;
    }
    //获取当前有多少个线程正在等待获取写入锁
    @Override
    public int getWaitingWriters() {
        return waitingWriters;
    }
    //使读线程的数量增加
    public void incrementReadingReaders(){
        this.readingReaders++;
    }
    //使读取线程的数量减少
    public void decrementReadingReaders(){
        this.readingReaders--;
    }
    //获取当前有多少个线程正在进行读操作
    @Override
    public int getReadingReaders() {
        return this.readingReaders;
    }
    //获取对象锁
    Object getMutex(){
        return this.MUTEX;
    }
    //获取当前是否偏向写锁
    boolean getPreferWriter(){
        return this.preferWriter;
    }
    //设置写锁偏好
    public void changePrefer(boolean preferWriter){
        this.preferWriter=preferWriter;
    }
}
public class ReadLock implements Lock {
    private final ReadWriteLockImpl mReadWriteLock;

    public ReadLock(ReadWriteLockImpl readWriteLock) {
        mReadWriteLock = readWriteLock;
    }

    @Override
    public void lock() throws InterruptedException {
        //使用Mutex作为锁
        synchronized (mReadWriteLock.getMutex()){
            //若此时有线程在进行写操作,或者有写线程在等待并且偏向写锁的标识为true时,就会无法获取该锁,只能被挂起
            while(mReadWriteLock.getWaitingWriters()>0
                    ||(mReadWriteLock.getPreferWriter()&&mReadWriteLock.getWaitingWriters()>0)){
                mReadWriteLock.getMutex().wait();
            }
            //成功获得读锁,并且使readingReaders的数量增加
            mReadWriteLock.incrementReadingReaders();
        }
    }

    @Override
    public void unlock() {
        //使用Mutex作为锁,并且进行同步
        synchronized (mReadWriteLock.getMutex()){
            //释放锁的过程就是使得当前reading的数量减1
            //将perferWriter设置为true,可以使得writer线程获得更多的机会
            //通知唤醒与Mutex关联的monitor waitSet中的线程
            mReadWriteLock.decrementReadingReaders();
            mReadWriteLock.changePrefer(true);
            mReadWriteLock.getMutex().notifyAll();
        }
    }
}
public class WriteLock implements Lock {
    private final ReadWriteLockImpl mReadWriteLock;

    public WriteLock(ReadWriteLockImpl readWriteLock) {
        mReadWriteLock = readWriteLock;
    }

    @Override
    public void lock() throws InterruptedException {
        synchronized (mReadWriteLock.getMutex()){
            try {
                //首先使等待获取写入锁的数字加1
                mReadWriteLock.incrementWaitingWriters();
                //如果此时有其他线程正在进行读操作,或者写操作,那么当前线程将被挂起
                while (mReadWriteLock.getReadingReaders() > 0
                        || (mReadWriteLock.getWritingWriters() > 0)) {
                    mReadWriteLock.getMutex().wait();
                }
            }finally {
                //成功获取到了写入锁,使得等待获取写入锁的计数器减1
                this.mReadWriteLock.decrementWaitingWriters();
            }
            //将正在写入的线程数量加1
            mReadWriteLock.incrementWritingWriters();
        }
    }

    @Override
    public void unlock() {
        synchronized (mReadWriteLock.getMutex()){
            //减少正在写入锁的线程计数器
            mReadWriteLock.decrementWritingWriters();
            //将偏好状态修改为false,可以使得读锁被最快速的获得
            mReadWriteLock.changePrefer(false);
            //通知唤醒其他在Mutex,monitor waitset中的线程
            mReadWriteLock.getMutex().notifyAll();
        }
    }
}
public class ShareData {
    //定义共享数据
    private final List<Character> container=new ArrayList<>();
    //构造ReadWriteLock
    private final ReadWriteLock mReadWriteLock= ReadWriteLock.readWriteLock();
    //创建读取锁
    private final Lock readLock=mReadWriteLock.readLock();
    //创建写入锁
    private final Lock writeLock=mReadWriteLock.writeLock();
    private final int length;

    public ShareData(int length) {
        this.length = length;
    }
    public char[] read(){
        try {
            readLock.lock();
            char[] newBuffer=new char[container.size()];
            for (int i = 0; i < container.size(); i++) {
                newBuffer[i]=container.get(i);
            }
            slowly();
            return newBuffer;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //当所有的操作都完成之后,对写锁进行释放
            writeLock.unlock();
        }
        return null;
    }
    public void write(char c){
        try {
            writeLock.lock();
                this.container.add(c);
            slowly();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //当所有的操作都完成之后,对写锁进行释放
            writeLock.unlock();
        }
    }
    private void slowly(){
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class ReadWriteLockTest {
    private final static String text="This";
    public static void main(String [] args){
        //定义共享数据
        final ShareData shareData=new ShareData(text.length()*9);
        //创建两个线程进行数据写操作
        for (int i = 0; i < 9; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < text.length(); j++) {
                        char c=text.charAt(j);
                        shareData.write(c);
                        System.out.println(currentThread()+"write"+c);
                    }
                }
            }).start();
        }
        //创建10个线程进行数据读操作
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        while (true) {
                            System.out.println(currentThread() + "read: " + new String(shareData.read()));
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}
Thread[Thread-0,5,main]write: T
Thread[Thread-0,5,main]write: h
Thread[Thread-4,5,main]write: T
Thread[Thread-1,5,main]write: T
Thread[Thread-5,5,main]write: T
Thread[Thread-5,5,main]write: h
Thread[Thread-1,5,main]write: h
Thread[Thread-7,5,main]write: T
Thread[Thread-8,5,main]write: T
Thread[Thread-6,5,main]write: T
Thread[Thread-0,5,main]write: i
Thread[Thread-0,5,main]write: s
Thread[Thread-7,5,main]write: h
Thread[Thread-7,5,main]write: i
Thread[Thread-7,5,main]write: s
Thread[Thread-1,5,main]write: i
Thread[Thread-6,5,main]write: h
Thread[Thread-2,5,main]write: T
Thread[Thread-2,5,main]write: h
Thread[Thread-2,5,main]write: i
Thread[Thread-5,5,main]write: i
Thread[Thread-5,5,main]write: s
Thread[Thread-1,5,main]write: s
Thread[Thread-8,5,main]write: h
Thread[Thread-8,5,main]write: i
Thread[Thread-8,5,main]write: s
Thread[Thread-2,5,main]write: s
Thread[Thread-4,5,main]write: h
Thread[Thread-4,5,main]write: i
Thread[Thread-6,5,main]write: i
Thread[Thread-6,5,main]write: s
Thread[Thread-3,5,main]write: T
Thread[Thread-3,5,main]write: h
Thread[Thread-3,5,main]write: i
Thread[Thread-4,5,main]write: s
Thread[Thread-3,5,main]write: s
Thread[Thread-13,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-9,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-16,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-12,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-10,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-17,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-12,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-18,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-16,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-11,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-10,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-9,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss

相关文章

  • 读写锁分离设计

  • ReadWriteLock读写锁

    1、引入ReadWriteLock读写锁 ReadWriteLock是JDK5中提供的读写分离锁。读写分离锁可以有...

  • java初入多线程9

    ReadWriteLock 多写锁 ReadWriteLock 是JDK5中提供的读写分离锁,读写分离可以有效的帮...

  • 八:ReadWriteLock 读写锁

    ReadWriteLock 是读写分离锁, 使用读写分离锁可以有效的帮助减少锁竞争.因为读操作完全不需要对代码块加...

  • Java并发编程-读写锁(ReentrantReadWriteL

    章节目录 ReentrantReadWriteLock 特性 读写锁接口示例 读写锁的实现分析读写状态设计写锁的释...

  • 第4章 锁的优化及注意事项

    提高锁性能的几点建议减小锁持有时间减小锁粒度读写分离锁替换独占锁(读多写少的场景)锁分离(LinkedBlocki...

  • ReadWriteLock和CountDownLatch

    ReadWriteLock读写锁 读写分离锁可以有效帮助减少锁竞争以提高系统性能。比如线程A1、A2、A3进行写操...

  • 锁的性能提升

    对于锁的性能提升的考虑,主要包括以下几点 减小锁持有时间 减小锁粒度 读写分离锁来替换独占锁 锁分离 锁粗化 1....

  • 减小锁的持有时间 减小锁的粒度 读写分离 使用原子操作

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

    多线程对于共享资源可以进行写操作和读操作,容易存在并发问题。必须要确保以下三点: 多线程可以同时对共享资源进行读操...

网友评论

      本文标题:读写锁分离设计

      本文链接:https://www.haomeiwen.com/subject/shvzlqtx.html