文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java并发编程ReentrantReadWriteLock加读锁流程

2023-05-19 17:10

关注

正文

protected final int tryAcquireShared(int unused) {
    Thread current = Thread.currentThread();
    int c = getState();
    if (exclusiveCount(c) != 0 &&
        getExclusiveOwnerThread() != current)
        return -1;
    int r = sharedCount(c);
    if (!readerShouldBlock() &&
        r < MAX_COUNT &&
        compareAndSetState(c, c + SHARED_UNIT)) {
        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;
    }
    return fullTryAcquireShared(current);
}

上面是尝试加读锁流程的代码,既然这篇是番外篇,那就不按正常流程一点一点去分析了,着重拿出一部分来分析一下。ReentrantReadWriteLockReentrantLock相比,除了多了读写锁之外,还增加了很多属性,比如firstReaderfirstReaderHoldCountcachedHoldCounter......那我们这篇文章就介绍一下这些新属性的含义以及上面代码中加锁成功后的处理。

属性介绍

static final class HoldCounter {
    int count = 0;
    final long tid = getThreadId(Thread.currentThread());
}

HoldCount类型用来存储线程ID和线程持有的读锁数量

private transient ThreadLocalHoldCounter readHolds;
static final class ThreadLocalHoldCounter
    extends ThreadLocal&lt;HoldCounter&gt; {
    public HoldCounter initialValue() {
        return new HoldCounter();
    }
}

readHolds通过ThreadLocal在线程本地存储了一个HoldCounter对象,表示当前线程持有的读锁重入数量,主要是为了方便在发生重入或者释放锁时,分别计算每个线程持有的读锁数量。

private transient HoldCounter cachedHoldCounter;

cachedHoldCounter存储的是最后一个获取读锁成功的线程持有的读锁数量。但是如果只有一个线程获取读锁,会使用firstReaderfirstReaderHoldCount来记录线程持有读锁数量,只有获取读锁的线程数大于1时才会用cachedHoldCounter存储最后线程持有的读锁数量。

private transient Thread firstReader = null;

第一个获取读锁的线程,确切地说是把读锁数量从0改成1的线程,并且当前还没有释放锁。如果第一个线程释放了锁,就会把firstReader设为null,只有当所有读锁释放之后,下一个获取读锁成功的线程就成为firstReader

private transient int firstReaderHoldCount;

第一个获取读锁的线程持有读锁的数量。

加锁成功处理

int r = sharedCount(c);
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++;
}

这里截取加锁成功之后处理的代码来分析下对这些属性的操作。

以上就是Java并发编程ReentrantReadWriteLock番外的详细内容,更多关于Java并发ReentrantReadWriteLock的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯