zoukankan      html  css  js  c++  java
  • 11.深入理解读写锁ReentrantReadWriteLock

    protected final int tryAcquireShared(int unused) {
    /*
    * Walkthrough:
    * 1. If write lock held by another thread, fail.
    * 2. Otherwise, this thread is eligible for
    * lock wrt state, so ask if it should block
    * because of queue policy. If not, try
    * to grant by CASing state and updating count.
    * Note that step does not check for reentrant
    * acquires, which is postponed to full version
    * to avoid having to check hold count in
    * the more typical non-reentrant case.
    * 3. If step 2 fails either because thread
    * apparently not eligible or CAS fails or count
    * saturated, chain to version with full retry loop.
    */
    Thread current = Thread.currentThread();
    int c = getState();
    //1. 如果写锁已经被获取并且获取写锁的线程不是当前线程的话
    // 线程获取读锁失败返回-1
    if (exclusiveCount(c) != 0 &&
    getExclusiveOwnerThread() != current)
    return -1;
    int r = sharedCount(c);
    if (!readerShouldBlock() &&
    r < MAX_COUNT &&
    //2. 当前线程获取读锁
    compareAndSetState(c, c + SHARED_UNIT)) {
    //3. 下面的代码主要是新增的一些功能,比如getReadHoldCount()方法
    //返回当前获取读锁的次数
    if (r == 0) {
    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;
    }
    //4. 处理在第二步中CAS操作失败的自旋已经实现重入性
    return fullTryAcquireShared(current);
    }

  • 相关阅读:
    MFC自绘框架窗口客户区
    命令行下创建mysql数据库
    linux重置mysql root密码的6种方
    xampp修改mysql默认密码详解
    Java常用包装类
    Java异常处理
    Java数组
    Java流程控制
    Java基本数据类型
    golang https server分析
  • 原文地址:https://www.cnblogs.com/itxiaok/p/10356582.html
Copyright © 2011-2022 走看看