ReentrantReadWriteLock 源码解析

概念:

        ReentrantLock的增强版本,内部维护了一对读写锁,适用于读多写少的场景。

特性:

        带有锁饥饿的问题,一旦读操作比较多的时候,想要获取写锁就变得比较困难。

        可以进行锁降级,由写锁过渡到读锁,可以 增强数据的可见性,减少读锁阻塞的情况。

ReentrantReadWriteLock和ReentrantLock的性能对比:

        可以看到ReentrantReadWriteLock在读多写少的场景下的性能提升不是一点半点。

**
 * @author maoyouhua
 * @version jdk21
 */
public class ReentrantReadWriteLockDemo {

    private int number = 0;
    private final ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    private final ReentrantLock readWriteLock = new ReentrantLock();

    public void lockRead(){
        readWriteLock.lock();
        try {
            TimeUnit.MILLISECONDS.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        readWriteLock.unlock();
    }

    public void lockWrite(int incr){
        readWriteLock.lock();
        number += incr;
        try {
            TimeUnit.MILLISECONDS.sleep(30);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        readWriteLock.unlock();
    }

    public void readWriteLockRead(){
        reentrantReadWriteLock.readLock().lock();
        try {
            TimeUnit.MILLISECONDS.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        reentrantReadWriteLock.readLock().unlock();
    }

    public void readWriteLockWrite(int incr){
        reentrantReadWriteLock.writeLock().lock();
        number += incr;
        try {
            TimeUnit.MILLISECONDS.sleep(30);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        reentrantReadWriteLock.writeLock().unlock();
    }

    /**
     * ReentrantLock执行时间是:17229
     * ReentrantReadWriteLock执行时间是:1705
     */
    public static void main(String[] args) throws InterruptedException {

        int readSize = 1000;
        int writeSize = 50;
        var demo = new ReentrantReadWriteLockDemo();

        var read = new CountDownLatch(readSize);
        var write = new CountDownLatch(writeSize);
        var readWriteLockRead = new CountDownLatch(readSize);
        var readWriteLockWrite = new CountDownLatch(writeSize);

        long start = System.currentTimeMillis();
        for (int i = 0; i < writeSize; i++) {
            new Thread(() ->{
                demo.lockWrite(1);
                write.countDown();
            },"Thread - write -" + i).start();
        }
        for (int i = 0; i < readSize; i++) {
            new Thread(() ->{
                demo.lockRead();
                read.countDown();
            },"Thread - read -" + i).start();
        }
        read.await();
        write.await();
        long end = System.currentTimeMillis();
        System.out.println("ReentrantLock执行时间是:" + (end - start));
        System.out.println(demo.number);


        start = System.currentTimeMillis();
        for (int i = 0; i < writeSize; i++) {
            new Thread(() ->{
                demo.readWriteLockWrite(1);
                readWriteLockWrite.countDown();
            },"Thread - write -" + i).start();
        }
        for (int i = 0; i < readSize; i++) {
            new Thread(() ->{
                demo.readWriteLockRead();
                readWriteLockRead.countDown();
            },"Thread - read -" + i).start();
        }
        readWriteLockRead.await();
        readWriteLockWrite.await();
        end = System.currentTimeMillis();
        System.out.println("ReentrantReadWriteLock执行时间是:" + (end - start));
        System.out.println(demo.number);
    }
}
        源码解析:
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值