zoukankan      html  css  js  c++  java
  • ReentrantReadWriteLock 源码分析

    ReentrantReadWriteLock  源码分析:

    1:数据结构:

    成员变量:

    private final ReentrantReadWriteLock.ReadLock readerLock; //读取锁

    private final ReentrantReadWriteLock.WriteLock writerLock; //写入锁

    final Sync sync;    //Sync 对象,继承AQS对象

    2:构造函数:

    public ReentrantReadWriteLock() {

            this(false); 

    }

    public ReentrantReadWriteLock(boolean fair) {   //默认 fair= false

            sync = fair ? new FairSync() : new NonfairSync();  //默认创建一个 NonfairSync

            readerLock = new ReadLock(this);     //创建读取锁

            writerLock = new WriteLock(this);     //创建写入锁

    }

    3:接下来分析ReadLock 读取锁;

      1):成员变量:

    private final Sync sync;   // ReadLock 内部维护的Sync对象,和ReentrantReadWriteLock中维护的Sync对象一致;

      2):构造方法:

      protected ReadLock(ReentrantReadWriteLock lock) {

                sync = lock.sync;   //将ReentrantReadWriteLock 构造函数中创建的Sync对象赋给ReadLock 中的Sync属性

            }

    4:下面分析ReadLock中的lock方法;

    public void lock() {

                sync.acquireShared(1);

            }

    acquireShared方法如下:

    public final void acquireShared(int arg) {  // arg=1

            if (tryAcquireShared(arg) < 0)

                doAcquireShared(arg);

        }

    下面依次分析 tryAcquireShared  doAcquireShared这两个方法:

    1): tryAcquireShared    方法:

      protected final int tryAcquireShared(int unused) {  // unused=1

                Thread current = Thread.currentThread();  //当前线程

                int c = getState();          //锁被持有的次数

                if (exclusiveCount(c) != 0 &&

                    getExclusiveOwnerThread() != current)  //若为互斥锁 且持有锁的线程不是当前线程则返回-1;

                    return -1;

                int r = sharedCount(c);  /获取锁的共享次数

                if (!readerShouldBlock() &&

                    r < MAX_COUNT && //锁不需要阻塞等待,共享次数小于最大值,共享次数+1

                    compareAndSetState(c, c + SHARED_UNIT)) {

                   if (r == 0) {  //第一次获取读取锁 则返回1 获取成功

                        firstReader = current;

                        firstReaderHoldCount = 1;

                    } else if (firstReader == current) {  //同一线程第二次后获取锁

                        firstReaderHoldCount++;    //持有锁的次数++

                    } else {   //当其他线程获取锁时会进入这个逻辑

                        HoldCounter rh = cachedHoldCounter;

                        if (rh == null || rh.tid != getThreadId(current))

                            cachedHoldCounter = rh = readHolds.get();

                        else if (rh.count == 0)

                            readHolds.set(rh);

                        rh.count++;

                    }

                    return 1;

                }

                return fullTryAcquireShared(current);  //当队列中首个节点是独占锁时会进入这个逻辑  这里就不分析了

            }

  • 相关阅读:
    设计模式-策略模式
    JavaCV开发详解之19:如何开启GPU硬件加速,使用JavaCV进行音视频的硬解码和硬编码(支持intel、amd和nvidia)
    javaCV开发详解之18:音视频转码(音频编解码和视频编解码)
    JavaCV入门指南:FrameConverter转换工具类及CanvasFrame图像预览工具类(javaCV教程完结篇)
    JavaCV入门指南:帧过滤器(FrameFilter)的原理与应用
    JavaCV入门指南:调用opencv原生API和JavaCV是如何封装了opencv的图像处理操作?
    javaCV开发详解之17:GIF和APNG动态图片推流和录制成视频文件(以gif转mp4和apng转mp4为例)
    javaCV开发详解之16:使用一张图片推流和一张图片录制成视频文件
    JavaCV入门指南:帧录制器/推流器(FrameRecorder)的原理与应用
    JavaCV入门指南:帧抓取器(FrameGrabber)的原理与应用
  • 原文地址:https://www.cnblogs.com/beppezhang/p/11214693.html
Copyright © 2011-2022 走看看