Skip to main content

moregeek program

reentrantlock原理,reentrantlock和synchronized区别_write less,do more。的博客-多极客编程

@[toc]


ReentrantLock原理


重入锁ReentrantLock,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁,而不会造成自己阻塞自己。重进入是指任意线程在获取到锁之后能够再次获取该锁而不会被锁所阻塞。
ReentrantLock虽然没能像synchronized关键字一样支持隐式的重进入,但是在调用lock()方法时,已经获取到锁的线程,能够再次调用lock()方法获取锁而不被阻塞。
除此之外,该锁的还支持获取锁时的公平和非公平性选择。实际上,公平的锁机制往往没有非公平的效率高,但是,并不是任何场景都是以TPS作为唯一的指标,公平锁能够减少“饥饿”发生的概率,等待越久的请求越是能够得到优先满足。
公平性锁保证了锁的获取按照FIFO原则,而代价是进行大量的线程切换。非公平性锁虽然可能造成线程“饥饿”,但极少的线程切换,保证了其更大的吞吐量。
在Java里一共有两类锁, 一类是synchornized同步锁,还有一种是JUC里提供的锁Lock,Lock是个接口,其核心实现类就是ReentrantLock。
ReentrantLock主要利用CAS+AQS队列来实现 ,主要是采用自旋锁,循环调用CAS操作来实现加锁,避免了使线程进入内核态的阻塞状态。
CAS:Compare and Swap,比较并交换。CAS有3个操作数:内存值V、预期值A、要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。该操作是一个原子操作,被广泛的应用在Java的底层实现中。在Java中,CAS主要是由sun.misc.Unsafe这个类通过JNI调用CPU底层指令实现


ReentrantLock和synchronized区别


可重入性:两者的锁都是可重入的,差别不大,有线程进入锁,计数器自增1,等下降为0时才可以释放锁
锁的实现:synchronized是基于JVM实现,操作系统级别(用户很难见到,无法了解其实现),ReentrantLock是JDK实现的,可以查到到对应实现的源码。
公平锁:synchronized只能是非公平锁。而ReentrantLock可以实现公平锁和非公平锁两种。
超时设置:synchronized不能设置超时,而Lock可以设置超时。
中断等待:synchronized不能中断一个等待锁的线程,而Lock可以中断一个试图获取锁的线程。
性能区别:在最初的时候,二者的性能差别差很多,当synchronized引入了偏向锁、轻量级锁(自选锁)后,二者的性能差别不大,官方推荐synchronized(写法更容易、在优化时其实是借用了ReentrantLock的CAS技术,试图在用户态就把问题解决,避免进入内核态造成线程阻塞)
功能区别



  • 便利性:synchronized更便利,它是由编译器保证加锁与释放,不会产生死锁。ReentrantLock是需要手动释放锁,所以为了避免忘记手工释放锁造成死锁,所以最好在finally中声明释放锁。
  • 锁的细粒度和灵活度,ReentrantLock优于synchronized

ReentrantLock独有的功能



  • 可指定是公平锁还是非公平锁,所谓公平锁就是先等待的线程先获得锁
  • 提供了一个Condition类,可以分组唤醒需要唤醒的线程
  • 提供能够中断等待锁的线程的机制,lock.lockInterruptibly()

    ReentrantLock 和synchronized应该怎么选?


    从上边的介绍,看上去ReentrantLock不仅拥有synchronized的所有功能,而且有一些功能synchronized无法实现的特性。性能方面,ReentrantLock也不比synchronized差,那么到底我们要不要直接使用ReentrantLock放弃使用synchronized呢?答案是不要这样做。
    J.U.C包中的锁定类是用于高级情况和高级用户的工具,除非说你对Lock的高级特性有特别清楚的了解以及有明确的需要,或这有明确的证据表明同步已经成为可伸缩性的瓶颈的时候,否则我们还是继续使用synchronized。相比较这些高级的锁定类,synchronized还是有一些优势的,比如synchronized不可能忘记释放锁。还有当JVM使用synchronized管理锁定请求和释放时,JVM在生成线程转储时能够包括锁定信息,这些信息对调试非常有价值,它们可以标识死锁以及其他异常行为的来源。在确实需要一些 synchronized 所没有的特性的时候,比如时间锁等候、可中断锁等候、无块结构锁、多个条件变量或者轮询锁。 ReentrantLock 还具有可伸缩性的好处,应当在高度争用的情况下使用它,但是请记住,大多数 synchronized 块几乎从来没有出现过争用,所以可以把高度争用放在一边。我建议用 synchronized 开发,直到确实证明 synchronized 不合适,而不要仅仅是假设如果使用 ReentrantLock “性能会更好”。总之,如果需要实现ReenTrantLock的三个独有功能时,就选择使用ReenTrantLock, 通常情况下synchronized就能够满足了,而且使用起来简单,由JVM管理,不会产生死锁。




本文内容到此结束了,
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位大佬指出。
主页共饮一杯无的博客汇总👨‍💻


保持热爱,奔赴下一场山海。🏃🏃🏃



在这里插入图片描述

©著作权归作者所有:来自51CTO博客作者共饮一杯无的原创作品,请联系作者获取转载授权,否则将追究法律责任
ReentrantLock原理,ReentrantLock和synchronized区别
https://blog.51cto.com/zhanjq/5554301

springmvc源码解析-dodispatch方法_wx62e0b69890c77的博客-多极客编程

断点入口容器启动后,我们根据URL访问接口,我们的DispatcherServlet都做了什么操作呢?我们可以​​在DispatcherServlet​​类中的​​doDispatch​​方法中打断点来详细查看;为什么直接在doDispatch方法中打断点?由图可知​​DispatcherServlet​​继承自​​HttpServlet​​抽象类,我们的get/post请求分别会请求其​​doG

springboot+shardingspherejdbc实现读写分离!_码农小宋的博客-多极客编程

1 概述本文讲述了如何使用​​MyBatisPlus​​+​​ShardingSphereJDBC​​进行读写分离,以及利用​​MySQL​​进行一主一从的主从复制。具体步骤包括:​​MySQL​​主从复制环境准备(Docker)搭建ShardingShpereJDBC+MyBatisPlus+Druid环境测试2 环境​​OpenJDK 17.0.3​​​​Spring Boot 2.7.0​​

#yyds干货盘点# leetcode算法题:二叉树的层序遍历_灰太狼_cxh的博客-多极客编程

题目:给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1:输入:root = [3,9,20,null,null,15,7]输出:[[3],[9,20],[15,7]]示例 2:输入:root = [1]输出:[[1]]示例 3:输入:root = []输出:[]代码实现:class Solution { public List<

分布式前修课:zookeeper锁实现方式_俗世游子的博客-多极客编程

前言 聊完MySQL和Redis,我们接下来在聊一聊Zookeeper。相信大家都已经发现了,这些都是我们在开发过程非常常用的技术。搞定他们,一切难题都不在话下。 Zookeeper,盘它 官网是我们学习某一种技术框架的第一手资料,通过官网我们能挖掘到该框架的最新动态 What Is Zookeeper Zookeeper是一款主要解决分布式协调的服务框架,可以用来维护配置信息、命名、提供分布式同

一起学习集合框架之 treeset_宇宙之一粟的漂泊之旅的博客-多极客编程

什么是 TreeSetTreeSet 是一个具有唯一元素的二叉树的集合,又被翻译为 树集。Java 中的 TreeSet 类是 Java 集合框架的一部分,从 Java 6 开始,它实现了 ​​NavigableSet​​ 接口(这个接口增加了几个查找元素以及反向遍历的便利方法),从而扩展了 ​​SortedSet​​ 集合。TreeSet 类与散列类十分相似,不过,它比普通的集合有所改进,树集是

@transactional指定回滚条件_梁云亮的博客-多极客编程

异常分类 可查的异常(checked exceptions):Exception下除了RuntimeException外的异常 不可查的异常(unchecked exceptions):RuntimeException及其子类和错误(Error) @Transactional注解属性详解 属性 类型 描述 value String 可选的限定描述符,指定使用的事务管理器 p

springmvc源码解析-dodispatch方法_wx62e0b69890c77的博客-多极客编程

断点入口容器启动后,我们根据URL访问接口,我们的DispatcherServlet都做了什么操作呢?我们可以​​在DispatcherServlet​​类中的​​doDispatch​​方法中打断点来详细查看;为什么直接在doDispatch方法中打断点?由图可知​​DispatcherServlet​​继承自​​HttpServlet​​抽象类,我们的get/post请求分别会请求其​​doG

#yyds干货盘点# 前端歌谣的刷题之路-第十九题-固定定位_前端歌谣的博客-多极客编程

 前言我是歌谣 我有个兄弟 巅峰的时候排名c站总榜19 叫前端小歌谣 曾经我花了三年的时间创作了他 现在我要用五年的时间超越他 今天又是接近兄弟的一天人生难免坎坷 大不了从头再来 歌谣的意志是永恒的 放弃很容易 但是坚持一定很酷 本题目源自于牛客网 微信公众号前端小歌谣题目请将html模块类为"box"的div元素固定在视口的左上角。​编辑 核心代码<!DOCTYPE html><

都2022年了,python web框架你不会只知道django和flask吧?_梦想橡皮擦的博客-多极客编程

写在前面 本文的诞生非常偶然,这两天一个小小小学弟问橡皮擦一个陈年旧问题,Python 基础学完了,想学习一个 Python Web 框架,是先学习 Django 呢,还是学习 Flask,现在的公司都用啥? 每次这个问题出现的时候,我都会给拉一个清单,这次咱们直接把它转换成文章吧。 标题就叫做《2022 年,你该学习的 Python Web 框架》 以下涉及的所有框架,都不提供官网和任何学习资料

分布式前修课:zookeeper锁实现方式_俗世游子的博客-多极客编程

前言 聊完MySQL和Redis,我们接下来在聊一聊Zookeeper。相信大家都已经发现了,这些都是我们在开发过程非常常用的技术。搞定他们,一切难题都不在话下。 Zookeeper,盘它 官网是我们学习某一种技术框架的第一手资料,通过官网我们能挖掘到该框架的最新动态 What Is Zookeeper Zookeeper是一款主要解决分布式协调的服务框架,可以用来维护配置信息、命名、提供分布式同

go开发微信小程序有哪些不错的第三方sdk_10982108的博客-多极客编程

本文已收录​​编程学习笔记​​。涵盖PHP、JavaScript、Linux、Golang、MySQL、Redis和开源工具等等相关内容。最近准备用Go语言开发微信小程序,发现会调用很多微信小程序的服务端接口,并且还需要自己封装。于是想着去GitHub上看看,是否有第三方现成的SDK直接拿来使用,结果发现两个非常不错的第三方库,这里分享给大家。SDK标准这里罗列几点,个人在使用第三方开源库的一些标

#yyds干货盘点#【愚公系列】2022年08月 go教学课程 005-变量_qq61972345e36b7的博客-多极客编程

一、变量 1.变量的定义 变量来源于数学,用于描述计算机中的数据存储空间。变量可以通过变量名访问。在指令式语言中,变量通常是可变的;但在纯函数式语言(如Haskell)中,变量可能是不可变(immutable)的。在一些语言中,变量可能被明确为是能表示可变状态、具有存储空间的抽象(如在Java和Visual Basic中);但另外一些语言可能使用其它概念(如C的对象)来指称这种抽象,而不严格地定义