当前位置:首页 > 数码 > 读写锁分离-一文深入理解如何实现读写锁 (读写锁使用)

读写锁分离-一文深入理解如何实现读写锁 (读写锁使用)

admin4个月前 (05-07)数码36
读写锁

在多线程编程中,共享资源访问是一个常见问题。为了防止线程安全问题,通常使用加锁的方式来避免线程安全问题,可以使用 synchronized 关键字以及一些显式锁操作,当然在分布式场景中还可以使用一些分布式锁机制来保证共享资源线程安全访问。

对于共享资源的访问,可以分为两种操作,一种是对共享资源的读操作,一种是对共享资源的写操作。如果有多个线程在同一时刻对共享资源的操作都是读操作的话,虽然是存在资源竞争的情况,但是并不会影响到最终的访问结果,也不会引起数据不一致的情况发生。这样时候,如果还是使用排他锁的方式进行加锁,很明显就有点得不偿失了。如下图所示,共享资源被多个线程共同进行读操作的时候,是不会出现线程安全问题的。

所以,如果在某个场景中,对于共享资源的读操作要明显多于写操作的时候,这个时候,读操作是可以不用进行加锁的。这样对系统的性能的提升也会非常明显。如图所示,在多个线程对共享资源进行写操作的时候,很明显,一定会造成资源的数据一致性问题出现。所以对于写操作来讲,一定要注意进行加锁的操作。

读写分离程序实现

1. 定义一个锁接口

public interface Lock {

    /
      进行加锁操作
     
      @throws InterruptedException
     /
    void lock() throws InterruptedException;

    /
      进行解锁操作
     /
    void unlock();
}
    

2. 读写锁接口实现

public interface ReadWriteLock{

    /
      创建读锁
     
      @return
     /
    Lock readLock();

    /
      创建写锁
     
      @return
     /
    Lock writeLock();

    /
      获取正在执行的写操作个数
     
      @return
     /
    int getDoingWriters();

    /
      获取正在等待执行的写操作个数
     
      @return
     /
    int getWaitingWriters();

    /
      获取正在执行的读操作个数
     
      @return
     /
    int getDoingReader();

    static ReadWriteLock readWriteLock() {
        return new ReadWriteLockImpl();
    }

    static ReadWriteLock readWriteLock(boolean preferWriter) {
        return new ReadWriteLockImpl(preferWriter);
    }
}
    

可以看到,在上面这个接口中定义了如下的一些操作:

  • 获取正在执行的写操作个数
  • 获取正在等待执行的写操作个数
  • 获取正在执行的读操作个数

为什么要有这些操作呢?其实这样写操作就是来规定如何去使用读写锁的,例如,读操作的个数大于0的时候,这个适合就意味着写操作的个数是等于0的。反之当写操作的个数大于0的时候,就意味着读操作的个数是等于0的。因为在读写操作的过程中,读操作和写操作是冲突的过程,也就是说在写的时候不能读,在读的时候不能写。那么通过这样的一个数量关系我们就可以实现什么时候加锁什么时候解锁了。

3. 按照规则实现读写锁

public class ReadWriteLockImpl implements ReadWriteLock {

    /
      定义锁对象
     /
    private final Object MUTEX = new Object();
    private int doingWriters = 0;
    private int waitingWriters = 0;
    private int doingReaders = 0;
    // ...
}
    

有了上面的规则的定义,那么一定要有规则的实现,上面的代码其实就是对上面的规则的实现。


如何使用C#读写锁ReaderWriterLockSlim

进入写入/读取模式有2种方法:EnterReadLock尝试进入写入模式锁定状态。 TryEnterReadLock(Int32) 尝试进入读取模式锁定状态,可以选择整数超时时间。 EnterWriteLock 尝试进入写入模式锁定状态。 TryEnterWriteLock(Int32) 尝试进入写入模式锁定状态,可以选择超时时间。

c或者c++普通互斥锁怎么实现读写锁

如果是单线程 不需要上锁。 如果是多线程,那么在访问共享区域的时候(共享内存,或者全局变量),在每次读或者写之前,上锁。 在读写结束后,再解锁就可以了。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: 读写锁