深挖锁(补充篇)

简介: 本文阅读大概需要8分钟。


一前记


针对公众号关注者针对Lock,synchronized和cmpxchg提出的疑问,这里特意补充一片来分析一下Lock和synchronized区别,以及cmpxchg的意义。


二Lock和synchronized的区别


我们在深挖锁上篇已经知道synchronized是由javac编译成moniterenter和moniterexit指令实现代码同步块的,也就是说synchronized的同步实现是由JVM对moniterenter与moniterexit指令的执行来实现的。而Lock类相关的锁实现是不依赖于JVM的虚拟机指令实现,而是直接通过java代码实现的。这里我们以重入锁ReetrantLock的lock方法的实现来说明:


static final class NonfairSync extends Sync {
    private static final long serialVersionUID = 7316153563782823691L;
    /**
     * Performs lock.  Try immediate barge, backing up to normal
     * acquire on failure.
     */
    final void lock() {
        if (compareAndSetState(0, 1))
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);
    }
    ...//省略
}


这里我们以ReentrantLock默认的非公平锁来进行分析,这里可以看到NonfairSync.lock()便是ReentrantLock.lock()的实现方法。ReentrantLock获取锁首先通过compareAndSetState()尝试将锁对象的state标志由期望值0设置为1,如果设置成功,则说明成功获取了锁,如果失败则通过调用同步队列的acquire()方法,将线程加入同步队列进行锁等待。这里compareAndSetState便是获取锁的关键实现,下面便是compareAndSetState的实现:


protected final boolean compareAndSetState(int expect, int update) {
    // See below for intrinsics setup to support this
    return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}


如果看过之前面“试题13解析-CAS与ABA”的同学应该对这个函数不陌生,正是CAS原子操作系列的函数,在处理器级别,CAS的原子性是由处理器对cmpxchg汇编指令加入LOCK_IF_MP前缀所提供的内存屏障进行保证的(深挖锁上篇),而synchronized对应的moniter虚拟机指令的也同样是由cmpxchg实现的。这里我们一定要理解原子性与锁是不同的概念,CAS为锁的加解锁操作提供了原子性操作的保证,但是CAS并不代表锁,CAS提供的是变量原子性操作的功能,例如Atomic包中的类的实现也是通过CAS来对变量进行原子性操作的。


其实,锁可以抽象成一个标记,线程尝试获取锁的过程,就是尝试将该标记设置为已上锁的过程,只要我们能保证只有一个线程可以成功设置该标记(即上锁过程的原子性),那么这个标记就是一把锁。Lock与synchronized(moniter指令)获取锁与释放锁过程中正是使用CAS来设置锁标志的。


Lock接口是JDK5之后提供的锁机制,其相对于关键字synchronized为程序员提供了更灵活的加锁解锁接口,以及公平锁非公平锁等更多的锁特性,本文意在解释原子性与锁的关系,为了避免陷入Lock实现的细节,因此这里就不展开说明Lock接口以及Lock实现依赖的同步队列AbstractQueuedSynchronizer的相关内容了。最后说一下区别synchronized是在JVM中实现的,而Lock的锁逻辑是Java层直接实现的。

相关文章
|
存储 缓存 Unix
微信小游戏制作工具中实现计时功能
微信小游戏制作工具中实现计时功能
610 0
|
jenkins 测试技术 应用服务中间件
【专业测试技能】全流程掌握:部署测试环境的策略与实践
本文分享了关于部署测试环境的策略与实践。文章讨论了部署测试环境的全过程,包括服务如MySQL、Redis、Zookeeper等的部署,以及解决服务间的依赖和兼容问题。文中还介绍了使用Jenkins、Docker等工具进行部署的方法,并通过实战案例讲解了如何创建和管理Jenkins Job、配置代理服务器Nginx、进行前后端服务的访问和优化。最后,作者强调了提问的重要性,并鼓励大家通过互联网解决遇到的问题。
463 2
【专业测试技能】全流程掌握:部署测试环境的策略与实践
|
机器学习/深度学习 人工智能 监控
利用人工智能审查代码:提升代码质量和安全性
【10月更文挑战第15天】本文探讨了AI在代码审查中的应用,介绍了AI辅助代码审查工具如何通过机器学习算法提升代码质量、检测潜在错误,并促进团队知识共享。文中还详细说明了实施AI辅助代码审查的步骤及其实战技巧,强调了结合人工审查、定制化模型和持续监控的重要性。
|
安全 Kotlin 容器
Kotlin 中的协变与逆变
Kotlin 中的协变与逆变
393 1
|
存储 缓存 资源调度
Vue3状态管理新选择:Pinia安装与使用详解,以及与Vuex的对比分析
Vue3状态管理新选择:Pinia安装与使用详解,以及与Vuex的对比分析
464 0
|
机器学习/深度学习 数据采集 索引
探索数据的维度:多元线性回归在实际应用中的威力
探索数据的维度:多元线性回归在实际应用中的威力
|
JavaScript 前端开发
鼠标拖拽菜单栏控制宽度大小及flex实现经典左右两栏布局
鼠标拖拽菜单栏控制宽度大小及flex实现经典左右两栏布局
842 120
鼠标拖拽菜单栏控制宽度大小及flex实现经典左右两栏布局
|
并行计算 负载均衡
多线程和多进程优缺点对比。
多线程和多进程优缺点对比。
495 1
|
人工智能 Python
Python asyncio 的 Future 和 Task
Python asyncio 的 Future 和 Task
279 1
|
人工智能 关系型数据库 分布式数据库
AI与云数据库的深度结合:黄铭钧院士点赞PolarDB,引领云数据库2.0时代
最近,阿里云PolarDB开发者大会的举办引起了广泛关注,中国科学院外籍院士、世界级数据库专家黄铭钧在阿里云PolarDB开发者大会上表示,AI与云数据库的深度结合是数据库发展的必然趋势。他点赞以PolarDB为代表的中国数据库正在引领全球云原生数据库的发展。那么本文就来简单聊聊AI与云数据库的深度结合,引领云数据库2.0时代,以及院士点赞国产数据库的意义和数据库产业突破的重要性和前景。
700 2
AI与云数据库的深度结合:黄铭钧院士点赞PolarDB,引领云数据库2.0时代