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

1 场景引入

在多线程的情况下访问共享资源,需要对资源进行同步操作以防止数据不一致的情况发生,通常我们可以使用synchronized关键字或者显式锁。

对资源的访问一般包括两种类型的动作——读和写(更新、删除、增加等资源会发生变化的动作),如果多个线程在某个时刻都在进行资源的读操作,虽然有资源的竞争,但是这种竞争不足以引起数据不一致的情况发生,那么这个时候直接采用排他的方式加锁,就显得有些简单粗暴了。

**其实多线程在同一时间都进行读操作时不会引起冲突之外,其余的情况都会导致访问的冲突,需要对资源进行同步处理。**比如说两个线程同时对数据读取,是不会引起冲突,但是如果一个都在写或者一个读取,一个写入就会引起冲突。

如果对某个资源读的操作明显多过于写的操作,那么多线程读时并不加锁,很明显对程序性能的提升会有很大的帮助

所以多线程下,如果读写分离,则可以提高效率,读数据是的是可以并行的,只有写的时候加锁串行

我们更多需求更多的时候就是读取的时候,允许多个线程去读取,但是在写如数据的时候,只能有一个线程去写入,其他线程不能进行读取和写入

2 简单实现

简单实现,简单了解一下读写锁的设计原理

根据上面的分析:

  • 多个线程读取数据是可以并行的,也就是说允许多个线程读取数据
  • 写数据的时候,只能允许一个线程在写数据,其他线程不能读也不能写

所以定义锁的时候,设计了一下几个变量:

/**
 * @Description: 当前正在读取数据线程数量
 */
private int readingThreads = 0;

/**
 * @Description: 等待去读取数据的线程的数量, 但是读取不了,放到了wait队列中
 */
private int waitReadThreads = 0;

/**
 * @Description: 正在写入数据的线程数量 只有一个
 */
private int writingThreads = 0;

/**
 * @Description: 记录当前有多少个线程想要写入,但是写入不了,放到了wait队列中,在等待其他释放锁
 */
private int waitWriteThreads = 0;
public class ReadWriteLock {
   
   

    /**
     * @Description: 当前正在读取数据线程数量
     */
    private int readingThreads = 0;

    /**
     * @Description: 等待去读取数据的线程的数量, 但是读取不了,放到了wait队列中
     */
    private int waitReadThreads = 0;

    /**
     * @Description: 正在写入数据的线程数量 只能有一个
     */
    private int writingThreads = 0;

    /**
     * @Description: 记录当前有多少个线程想要写入,但是写入不了,放到了wait队列中,在等待其他释放锁
     */
    private int waitWriteThreads = 0;

    /**
     * 加读锁
     */
    public synchronized void readLock() throws InterruptedException {
   
   
        // 获取锁的时候,有可能获取不到锁,进入到等待队列(waitSet)中, 所以waitReadThreads可能需要加1的
        this.waitReadThreads++;
        try {
   
   
            while (this.writingThreads > 0){
   
   
                // 此时有线程正在写数据,便需要等待不能进行读取数据
                // 不能在++,需要立刻等待,就放到外面,但是可能会记录的数量不对
                // this.waitReadThreads++;
                this.wait();
            }
            // 当前没有线程在写入数据,那么就可以读取数据
            this.readingThreads++; // 正在读取数据的线程数量++
        }finally {
   
   
            // 当释放掉锁的时候,waitReadThreads --
            this.waitReadThreads--;
        }
    }

    /**
     * 释放掉读锁
     */
    public synchronized void unReadLock(){
   
   
        // 当前正在读取数据线程数量 --
        this.readingThreads--;
        // 唤醒其他线程
        this.notifyAll();
    }


    /**
     * 加写锁
     */
    public synchronized void writeLock() throws InterruptedException {
   
   
        // 获取锁的时候,有可能获取不到锁,进入到等待队列(waitSet)中, 所以waitWriteThreads可能需要加1的
        this.waitWriteThreads++;
        try {
   
   
            while (this.writingThreads > 0 || this.readingThreads > 0){
   
   
                // 当有其他线程正在读取数据和写入数据的时候,此时不能写入数据,需要等待
                // this.waitWriteThreads++; // 同样也不能再这样++
                this.wait();
            }
            // 当前其他线程正在读取数据和写入数据的时候, 就可以写入数据了
            this.writingThreads++;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值