ReentrantLock源码阅读(1)(JDK1.8)

2023-05-16

ReentrantLock

  • 前言
  • ReentrantLock(JDK 1.8)
    • 实现了Lock接口
    • Sync类
    • NonfairSync类
    • FairSync类
    • 重要属性和方法
  • 总结


前言

最近在使用Java 并发包时遇到一些问题,感觉对于其还是不够了解,故开始着手阅读相关源码。


ReentrantLock(JDK 1.8)

实现了Lock接口

public interface Lock {
  
    void lock();
  
    void lockInterruptibly() throws InterruptedException;
  
    boolean tryLock();

    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

    void unlock();

    Condition newCondition();
}

Sync类

其内部抽象类,进一步继承了AbstractQueuedSynchronizer类,用于后续实现公平和非公平锁

final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
  	// 尚未有线程持有锁,直接获得
    if (c == 0) {
        if (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
   // 可重入,计数增加
    else if (current == getExclusiveOwnerThread()) {
        int nextc = c + acquires;
        if (nextc < 0) // overflow
            throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
    }
    return false;
}

protected final boolean tryRelease(int releases) {
    int c = getState() - releases;
  	// 如果当前线程没有获得锁则无法调用成功释放,抛出IllegalMonitorStateException
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    if (c == 0) {
        free = true;
        setExclusiveOwnerThread(null);
    }
    setState(c);
    return free;
}

NonfairSync类

NonfairSync类,静态final,继承自Sync。

static final class NonfairSync extends Sync {
    final void lock() {
        if (compareAndSetState(0, 1))	// 1
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);	// +1
    }

    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
}

FairSync类

static final class FairSync extends Sync {

    final void lock() {
        acquire(1);	// 没有再判断当前是否有线程持有锁,体现公平
    }

    /**
     * Fair version of tryAcquire.  Don't grant access unless
     * recursive call or no waiters or is first.
     */
    protected final boolean tryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {
          	// 如果队列前面没有节点,且当前锁并未被其他线程持有,则成功
            if (!hasQueuedPredecessors() &&
                compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        // 可重入 
        else if (current == getExclusiveOwnerThread()) {
            int nextc = c + acquires;
            if (nextc < 0)
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }
}

重要属性和方法

private final Sync sync;

两个构造函数,默认为非公平锁

public ReentrantLock() {
    sync = new NonfairSync();
}

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}
public void lock() {
    sync.lock();	// 调用Sync实现
}

public void unlock() {
  	sync.release(1);	// 调用Sync实现
}
public Condition newCondition() {
    return sync.newCondition();	// return new ConditionObject();
}

总结

lock()和unlock()的调用过程如下,本质锁其实就是一个volatile state值,在加上unsafe中的一些操作实现
lock()过程
unlock()过程
ReentrantLock相关继承类图如下图所示。
ReentrantLock相关继承类图

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ReentrantLock源码阅读(1)(JDK1.8) 的相关文章

  • CentOs7.5yum安装JDK1.8详细过程

    先查看有哪些可安装的 yum list java root 64 VM 16 35 centos yum list java Loaded plugins fastestmirror langpacks Loading mirror spe
  • CentOS8安装JDK1.8

    文章目录 linux服务器上安装JDK1 8参考文章 linux服务器上安装JDK1 8 起因是在CentOS8上执行jps命令时 xff0c 报错 xff1a root 64 localhost kafka 2 13 2 8 0 jps
  • Centos8安装jdk1.8

    1 查询可安装jdk列表 先查看是否安装 yum list installed grep java yum list java 2 安装jdk1 8 yum span class token operator span y install
  • Collections.sort和Arrays.sort在jdk1.6和jdk1.7中区别

    1 写这边文章的原因 xff1a 最近在线上产品环境发现了部分用户数据返回排序问题 xff08 和之前理想中的排序不太一样 xff09 xff0c 由于服务器是集群配置 xff0c 猜测肯定是某一台排序服务出了问题 xff08 之前工作中也
  • synchronized和ReentrantLock之间的区别

    synchronized和ReentrantLock的区别 synchronized是一个关键字 xff0c 是JVM内部实现的 xff1b ReentrantLock是标准库的一个类 xff0c 是JVM外部基于Java实现的 synch
  • (Linux)Debian下安装JDK1.8.0

    昨晚花了两个多小时查资料 xff0c 在Debian下安装了jdk和tomcat xff0c 记录一下 查看Linux版本 xff1a uname span class hljs operator a span 我的是64位的 在oracl
  • DispatcherServlet 源码阅读(1)

    有时间还是应该多看看源码 DispatcherServlet 是一个实实在在的 Servlet xff0c 所以 Spring MVC 引入后不会改变 Servlet 容器的行为 xff0c 仍然是解析 web xml 部署文件 xff0c
  • glibc源码阅读

    FBI warning 本文仅仅是试图以二进制选手的方式来理解mallo c中所使用的堆机制 xff0c 不会对具体操作以及堆块结构作过多叙述 xff0c 敬请谅解 水平欠佳 xff0c 有问题也欢迎留言指出 先解释一些常用的宏与常量 变量
  • MSCKF-vio源码阅读

    作为一个菜狗来说 xff0c 一开始弄明白kf ekf等滤波方法实属不易 xff0c 但是一旦理解原理之后再发散到基于滤波的状态估计方法 xff0c 学习起来就会事半功倍 xff0c 就像导航包中的robot pose ekf xff0c
  • 【cartographer_slam源码阅读】4-6激光雷达数据的转换

    HandleLaserScanMessage 函数 作用 xff1a 利用 ToPointCloudWithIntensities函数 将ros中的数据转换为carto中定义的数据类型 xff1b 传入 HandleLaserScan 函数
  • AbstractQueuedSynchronizer源码阅读(1)(AQS JDK1.8)

    AbstractQueuedSynchronizer 前言AbstractQueuedSynchronizer xff08 1 xff09 JDK 1 8 用途主要源码分析Node内部类ConditionObject类重要方法 主要的属性及
  • 源码阅读——validate-npm-package-name

    文章目录 前言一 源码阅读工具二 阅读源码1 目录结构2 package json3 index js 三 使用该包1 vue cli中使用2 create react app 中使用 总结 前言 validate npm package
  • ucos源码阅读3——信号量,互斥信号量(未完待续)

    ucos源码阅读3 信号量 xff0c 互斥信号量 事件控制块ECBInitEventList xff08 xff09 EventWaitListInit xff08 xff09 EventTaskRdy xff08 xff09 Event
  • Android Studio 配置 JDK1.8 使用Lambda表达式

    Android Studio 配置 JDK1 8 使用Lambda表达式 JDK1 8 添加几项新特性譬如对集合的优化语法的便捷配合Lambda表达式使用可以让代码更加简便美观 xff0c 但对于一些没有接触Lambda表达式的同学们来说就
  • “npm create vite“ 是如何实现初始化 Vite 项目?

    欢迎关注我的公号 前端我废了 查看更多文章 前言 我们从 vite 的官方文档中看到 可以使用 npm yarn pnpm create 命令来快速初始化一个基于 Vite 的项目 其实很多框架或库都会开发相应的脚手架工具 用于快速初始化项
  • JDK源码阅读之AbstractStringBuilder类

    AbstractStringBuilder类源码阅读 AbstractStringBuilder类的作用 AbstractStringBuilder类的类图 AbstractStringBuilder类的重点方法 属性变量 构造方法 精华方
  • java.concurrent.ReentrantLock - 为什么我们要多次获取相同的锁[重复]

    这个问题在这里已经有答案了 我知道如果使用 ReentrantLock 它允许同一线程多次获取同一锁 其内部有一个计数器来统计获取锁的次数 如果您两次获取同一个锁 则需要释放它两次 但我的问题是 为什么有人想要多次获取锁 一次获取就足够了吗
  • 为什么锁被捕获到局部变量

    在java JRE中我看到the code private final ReentrantLock lock public E poll final ReentrantLock lock this lock lock lock 为什么锁被捕
  • ReentrantLock 不起作用

    我不明白为什么代码不能正常工作 问题是 ReentrantLock 不会锁定 ThreadClass run 中的方法调用 假定其方法被锁定在 ThreadClass 中的资源类 public class ResourceClass pri
  • Java 可重入锁和条件 |生产者完成工作,消费者陷入困境

    一般信息 三个读取器线程从文件中随机读取块 每个块都有一个 ID 然后写入普通的 ArrayList 一旦具有所需 ID 的块被添加到列表中 写入线程就会写入输出文件 因此 我编写了一个 BlockingChunkList 它应该同步 ad

随机推荐

  • flex校验

    package cn newtouch flexDemo business validator import mx binding utils BindingUtils import mx containers FormItem impor
  • docker--最全的网络类型(7类)

    目录 1bridge桥接模式 xff08 默认 xff09 2 host 3 overlay 4 ipvlan 5 macvlan 6 none 7 container 官网有六类 xff1a Networking overview Doc
  • flex 国际化

    Flex 开发 xff08 国际化 xff09 在Flex4 之前默认只支持en US ja JP 这两种本地化 xff0c 因此如果想在Flex 中支持中文或者其他语言时 xff0c 需要额外的操作 xff1a 1 首先添加新的本地化支持
  • 使用mysqladmin命令来修改mysql的root密码

    一般mysql的root默认密码为空 xff0c 如果你之前并没有设置过root密码就使用mysqladmin命令 xff0c 你可以使用如下mysqladmin命令来修改root密码 1 2 3 mysqladmin u root p p
  • CCF化学方程式的配平

    include lt iostream gt include lt string gt include lt cctype gt include lt unordered map gt using namespace std unorder
  • CCF 201909-4 推荐系统

    include lt cstdio gt include lt set gt include lt unordered map gt include lt algorithm gt using namespace std typedef l
  • CCF 201903-4 消息传递接口

  • Docker学习笔记(一)

    Docker学习笔记 xff08 一 xff09 什么是Docker Docker 使用 Google 公司推出的 Go 语言 进行开发实现 xff0c 基于 Linux 内核的 cgroup xff0c namespace xff0c 以
  • Docker学习笔记(二)

    Docker镜像 Docker 镜像是一个特殊的文件系统 xff0c 除了提供容器运行时所需的程序 库 资源 配置等文件外 xff0c 还包含了一些为运行时准备的一些配置参数 xff08 如匿名卷 环境变量 用户等 xff09 Docker
  • Java多线程里共享变量线程安全问题的原因

    Java多线程里共享变量线程安全问题的原因 Java多线程里对于共享变量的操作往往需要考虑进行一定的同步互斥操作 xff0c 原来是因为Java内存模型导致的共享内存对于线程不可见 Java 内存模型规定 xff0c 将所有的变量都存放在主
  • 重构-改善既有代码的设计读书笔记一

    重构 定义 为何重构 改进软件设计 使软件更容易理解 帮助找到Bug提高编程速度 何时重构 添加功能修改错误复审 总而言之 xff0c 当你觉得代码的可读性 可维护性 可修改性到达一定难以接受的程度 xff0c 就可以开始考虑是否可以使用重
  • Spring文档学习笔记一

    Spring文档学习笔记一 目录 Spring文档学习笔记一 Spring的宗旨 主要特征 几个核心理念 IoC 依赖解析过程 Spring循环依赖的解决方式 更详细的得估计得看Spring源码 1 4 2 Dependencies and
  • python数据结构算法DAY2| 快速排序

    目录 快速排序 xff08 quick sort xff09 1 什么是快速排序 2 快速排序思路 3 快速排序代码 4快速排序复杂度 5 快速排序函数与冒泡排序的效率比较 6 快速排序的缺点 解决办法 xff1a 快速排序 xff08 q
  • Go里w http.ResponseWriter,调用w.Write()方法报错

    Go里w http ResponseWriter写入报错http request method or response status code does not allow 1 下面是报错截图 2 点进去Write方法 它首先是一个接口 x
  • CCF 202012-3 带配额的文件系统 练习

    大模拟 xff0c 没涉及什么算法主要是数据结构的设计 细节的考虑 xff0c 挺锻炼的 xff0c 记录一下 xff0c 代码加了注释 include lt iostream gt include lt string gt include
  • 多接口继承和多层抽象类设计理解

    多接口继承和多层抽象类设计理解 以JDK集合List框架为例有感 以后可能又会有新的理解 xff0c 先记录一下 设计得好的接口一般也要遵循单一职责原则 xff0c 最上层的接口一般属于独立的 xff0c 不再有依赖的 xff0c 如Ite
  • 202012-5 星际旅行 (线段树模板60分)记录一下

    include lt bits stdc 43 43 h gt using namespace std typedef long long ll const int maxn 61 1e5 43 5 const ll MOD 61 1e9
  • 联机象棋(1)

    联机象棋 xff08 1 xff09 需求架构与开发技术主要设计与实现1 棋盘 棋子布局2 选棋 下棋3 人人对战匹配4 判断是否被将5 通信模块6 其他如声音效果等提升用户体验7 人机对战 尚未实现 8 最终实现效果图 需求 登录 注册
  • AbstractQueuedSynchronizer源码阅读(1)(AQS JDK1.8)

    AbstractQueuedSynchronizer 前言AbstractQueuedSynchronizer xff08 1 xff09 JDK 1 8 用途主要源码分析Node内部类ConditionObject类重要方法 主要的属性及
  • ReentrantLock源码阅读(1)(JDK1.8)

    ReentrantLock 前言ReentrantLock JDK 1 8 实现了Lock接口Sync类NonfairSync类FairSync类重要属性和方法 总结 前言 最近在使用Java 并发包时遇到一些问题 xff0c 感觉对于其还