ReentrantLock(可重入锁)

ReentrantLock了解吗?是公平锁吗?

ReentrantLock(可重入锁) 实现了Lock接口,是一个可重入且独占式的锁,和synchronized关键字类似,不过ReentrantLock更灵活、强大,增加了轮询、超时、中断、公平锁和非公平锁等高级功能。

重入锁指在同一线程中,外部方法获得锁之后,内层递归方法依然可以获得该锁,如果锁不具备重入性,那么当同一个线程两次获取锁的时候就会发生死锁。

独占锁指该锁在同一时刻只能被一个线程获取,而获取锁的其他线程只能在同步队列中等待。

ReentrantLock默认使用非公平锁,也可以通过构造器显式指定公平锁。

  • 公平锁:锁被释放之后,先申请的线程先得到锁。性能较差,公平锁为了保证时间上的绝对顺序,上下文切换更频繁。
  • 非公平锁:锁被释放之后,后申请的线程可能会先获取到锁,是随机或者按照其他优先级排序的。性能更好,但可能会导致某些线程无法获取到锁。

synchronized与ReentrantLock的异同

  • 两者都是可重入锁

  • synchronized依赖于JVMReentrantLock依赖于API,synchronized是依赖于JVM的,而ReentrantLock是JDK层面实现的也就是API层面,需要lock()unlock()方法配合try/finally语句块来完成。

  • synchronized不需要用户手动释放锁,ReentrantLock则需要用户手动释放锁。

  • ReentrantLocksynchronized增加了一些高级功能:

    等待可中断:ReentrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly() 来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。

    可实现公平锁: ReentrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。ReentrantLock默认情况是非公平的,可以通过ReentrantLock类的ReentrantLock(boolean fair)构造方法来指定是否是公平的。

    可实现选择性通知(锁可以绑定多个条件) : synchronized关键字与wait()notify()/notifyAll()方法相结合可以实现等待/通知机制。ReentrantLock类当然也可以实现,但是需要借助于Condition接口与newCondition()方法。

ReentrantLock如何避免死锁:响应中断、可轮询锁、定时锁

(1)响应中断:在synchronized中如果有一个线程尝试获取一把锁,则其结果是要么获取锁继续执行,要么继续等待。ReentrantLock还提供了可响应中断的可能,即在等待锁的过程中,线程可以按需取消对锁的请求。

(2)可轮询锁:通过boolean tryLock()获取锁。如果有可用锁,则获取该锁并返回true,如果无可用锁,则立即返回false。

(3)定时锁:通过boolean tryLock(long time,TimeUnit unit) throws InterruptedException获取锁。如果在指定的时间内获取到了可用锁,且当前线程未被中断,则获取该锁并返回true。如果在指定的时间内获取不到可用锁,则将禁用当前线程,并且在发生如下三种情况之前,该线程一直处于休眠状态。

  • 当前线程获取到了可用锁并返回true。
  • 在当前线程进入此方法时若设置了该线程的中断状态,或者当前线程在获取锁时被中断,则将抛出InterruptedException,并清除当前线程的已中断状态。
  • 当前线程获取锁的时间超过了指定的等待时间,将返回false。如果设定的时间小于或等于0,则该方法将完全不等待。

ReentrantLock抢占锁的三种方法

  • lock()方法用于阻塞抢锁,抢不到锁时线程会一直阻塞。
  • tryLock()方法用于尝试抢锁,该方法有返回值,如果成功就返回true,如果失败(锁已被其他线程获取)就返回false。此方法无论如何都会立即返回,在抢不到锁时,线程不会像调用lock()方法那样一直被阻塞。
  • tryLock(long time,TimeUnit unit)方法和tryLock()方法类似,只不过这个方法在抢不到锁时会阻塞一段时间。如果在阻塞期间获取到锁就立即返回true,超时则返回false

(1)使用lock()方法

 
 public void lock()

模板代码如下:

 ReentrantLock lock = new ReentrantLock();lock.lock();    //1:抢占锁try {//2:抢锁成功,执行临界区代码} finally {lock.unlock();//3:释放锁}

注意:

  • 释放锁操作lock.unlock()必须在try-catch结构的finally块中执行,否则,如果临界区代码抛出异常,锁就有可能永远得不到释放。

  • 抢占锁操作lock.lock()必须在try语句块之外,而不是放在try语句块之内。

    原因一:lock()方法没有声明抛出异常,所以可以不包含到try块中。

    原因二:lock()方法并不一定能够抢占锁成功,如果没有抢占成功,当然也就不需要释放锁,而且在没有占有锁的情况下去释放锁,可能会导致运行时异常。

  • 在抢占锁操作lock.lock()和try语句之间不要插入任何代码,避免抛出异常而导致释放锁操作lock.unlock()执行不到,导致锁无法被释放。

(2)调用tryLock()方法非阻塞抢锁

public boolean tryLock()

lock()是阻塞式抢占,在没有抢到锁的情况下,当前线程会阻塞。

tryLock()是非阻塞式抢占,在没有抢到锁的情况下,当前线程会立即返回,不会被阻塞。

//创建锁对象
ReentrantLock lock = new ReentrantLock();
if(lock.tryLock()){//1:尝试抢占锁try {//2:抢锁成功,执行临界区代码} finally {lock.unlock();  //3:释放锁}
}else{//4:抢锁失败,执行后备动作
}

3)调用tryLock(long time,TimeUnit unit)方法抢锁

public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException

tryLock(long timeout, TimeUnit unit) throws InterruptedException方法用于限时抢锁,该方法在抢锁时会进行一段时间的阻塞等待,其中的time参数代表最大的阻塞时长,unit参数为时长的单位。

//创建锁对象
ReentrantLock lock = new ReentrantLock();
try {if(lock.tryLock(1, TimeUnit.SECONDS)){//1:尝试抢占锁try {//2:抢锁成功,执行临界区代码} finally {lock.unlock();  //3:释放锁}}else{//4:限时抢锁失败,执行后备动作}
} catch (InterruptedException e) {e.printStackTrace();
}

Condition

与Object对象的waitnotify两类方法类似,基于Lock显式锁,JUC也提供了一个用于线程间进行“等待-通知”方式实现的接口java.util.concurrent.locks.Condition

(1)Lock接口的主要方法

public interface Condition{//方法1:等待,使当前线程加入等待队列中,并释放当前锁//当其他线程调用signal()时,等待队列中的某个线程会被唤醒,重新去抢锁void await() throws InterruptedException;//方法2:通知。此方法在功能上与Object.notify()语义等效//唤醒一个在await()等待队列中的线程void signal();//方法3:通知全部。唤醒await()等待队列中所有的线程,此方法与Object.notifyAll()语义上等效void signalAll();//方法3:限时等待。此方法与await()语义上等效//不同点在于,在指定time等待超时后,如果没有被唤醒,线程将中止等待//线程等待超时返回false,其他情况返回trueboolean await(long time, TimeUnit unit) throws InterruptedException
}

Condition对象的signal(通知)方法和同一个对象的await(等待)方法是一一配对使用的,也就是说,一个Condition对象的signal(或signalAll)方法不能去唤醒其他Condition对象上的await线程。

Condition对象是基于显式锁的,所以不能独立创建一个Condition对象,而是需要借助于显式锁实例去获取其绑定的Condition对象。

不过,每一个Lock显式锁实例都可以有任意数量的Condition对象。具体来说,可以通过lock.newCondition()方法去获取一个与当前显式锁绑定的Condition实例,然后通过该Condition实例进行“等待-通知”方式的线程间通信。

 public class ReentrantLockCondition {//创建一个显式锁static Lock lock=new ReentrantLock();//获取一个显式锁绑定的Condition对象static private Condition condition=lock.newCondition();​//等待线程执行异步目标任务static class WaitTarget implements Runnable{@Overridepublic void run() {lock.lock();//1:抢占锁try {System.out.println("我是等待方");condition.await();//2:开始等待,并且释放锁System.out.println("收到通知,等待方继续执行");} catch (InterruptedException e) {e.printStackTrace();}finally {lock.unlock();//释放锁}​}}//通知线程的异步目标任务static class NotifyTarget implements Runnable{@Overridepublic void run() {lock.lock(); //3:抢锁try {System.out.println("我是通知方");condition.signal(); //4:发送通知System.out.println("发出通知了,但是线程还没有立马释放锁");} finally {lock.unlock();  //5:释放锁之后,等待线程才能获得锁}}}​public static void main(String[] args) throws InterruptedException {//创建等待线程Thread waitThread = new Thread(new WaitTarget(), "WaitThread");//启动等待线程waitThread.start();Thread.sleep(2000);//等待一会​//创建通知线程Thread notifyThread = new Thread(new NotifyTarget(), "NotifyThread");//启动通知线程notifyThread.start();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/126375.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【原创】java+swing+mysql无偿献血管理系统设计与实现

摘要: 无偿献血管理系统是为了实现无偿献血规范化、有序化、高效化的管理而设计的。本文主要介绍使用java语言开发一个基于C/S架构的无偿献血管理系统,提高无偿献血管理的工作效率。 功能分析: 系统主要提供给管理员、无偿献血人员&#x…

免费小程序商城搭建之b2b2c o2o 多商家入驻商城 直播带货商城 电子商务b2b2c o2o 多商家入驻商城 直播带货商城 电子商务

1. 涉及平台 平台管理、商家端(PC端、手机端)、买家平台(H5/公众号、小程序、APP端(IOS/Android)、微服务平台(业务服务) 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

C语言--输出格式控制(printf函数)--宽度精度控制

格式输出函数printf printf(格式控制,输出表列) 基本用法 格式字符功能例子d输出一个有符号的十进制整数printf("%d %d",12,-56);c输出一个字符 char ch a; printf("%c",ch); s输出一个字符串printf("%s","oh my god&…

vins fusion 学习(更新中)

vins fusion 学习(更新中) RVIZ图像: 绿色的是里程计路径 图像中红色的是特征点 红色框是相机 白色的小点是图像中的特征点对应到空间中的特征点 使用rosrun rqt_graph rqt_graph得到节点订阅图 可以看到rosbag发布了以下数据 imu&#xff…

打字练习软件 Type Fu mac中文版技能介绍

Type Fu mac是一款打字练习和提高打字速度的应用程序。它旨在帮助用户通过练习键盘打字,提高打字准确性和速度。无论您是初学者还是想要提高打字技能的专业人士,Type Fu都是一个很好的选择! Type Fu mac采用了一种互动,游戏化的方…

Qt之基于QCustomPlot绘制直方图(Histogram),叠加正态分布曲线

一.效果 二.原理 1.正态分布 高斯分布(Gaussian distribution),又名正态分布(Normal distribution),也称"常态分布",也就是说,在正常的状态下,一般的事物,都会符合这样的分布规律。 比如人的身高为一个随机变量,特别高的人比较少,特别矮的也很少,大部分都…

服务器遭受攻击如何处理(记录排查)

本文的重点是介绍如何鉴别安全事件以及保护现场的方法,以确保服务器负责人能够在第一时间对安全攻击做出反应,并在最短时间内抵御攻击或减少攻击所带来的影响。 在服务器遭遇疑似安全事件时,通常可以从账号、进程、网络和日志四个主要方面进…

golang 实现雪花算法

雪花算法概述 snowflake 是 twitter 开源的分布式ID生成算法,其核心思想为,一个long型的ID: 41 bit 作为毫秒数 - 41位的长度可以使用69年10 bit 作为机器编号 (5个bit是数据中心,5个bit的机器ID) - 10位…

【机器学习】项目数据处理部分

文章目录 前言项目理解数据探索特征工程总结 前言 本文参考《阿里云天池大赛赛题解析》,拿到一个项目或者赛题,使用机器学习来进行预测分类,需要以下七个步骤: 项目(赛题)理解数据探索特征工程模型训练模…

阿里云老用户优惠服务器99元/年?良心了!

阿里云老用户优惠服务器99元/年,谁再说阿里云不好我给谁急,云服务器ECS配置为经济型e实例,2核CPU、2G内存、3M固定带宽、40G ESSD entry 系统盘,老用户优惠价99元一年,老用户可以买,当然新用户也可以买&…

JS 去除字符串中所有标点符号

直接上代码了 var str 这是《书》中的一段&#xff0c;两段文字。; var new_str str.replace(/[:_.~!#$%^&*() \ <>?"{}|, \/ ; \\ [ \] ~&#xff01;#&#xffe5;%……&*&#xff08;&#xff09;—— \ {}|《》&#xff1f;&#xff1a;“”【】、&a…

面经(面试经验)第一步,从自我介绍开始说起

看到一位同学讲自己的面试步骤和过程&#xff0c;我心有所感&#xff0c;故此想整理下面试的准备工作。以便大家能顺利应对面试&#xff0c;通过面试... 求职应聘找工作&#xff0c;面试是必然的关卡&#xff0c;如今竞争激烈呀&#xff0c;想要得到自己喜欢的工作&#xff0c…

翻页电子版照片书如何制作?

在漫长的生命长河里&#xff0c;经常会拍很多漂亮的照片&#xff0c;这些照片可以收集起来做成相册&#xff0c;也可以制作成照片书&#xff0c;无论是当作礼物送给家人朋友&#xff0c;还是留着自己细细品味欣赏&#xff0c;都非常的有意义。 如今市面上制作翻页照片书的线上平…

概念解析 | 揭开心电图测量的神秘面纱

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:ECG的测量原理 揭开心电图测量的神秘面纱 How to read an ECG – Physical Therapy Reviewer 1. 背景介绍 心电图(ECG)是记录心脏电活动的过程,它反映了心脏在收缩和舒张期间的…

希亦T800 Pro双滚刷双活水洗地机发布:颠覆纯水洗,水汽混动技术的旗舰新杰作

11月1日&#xff0c;CEYEE希亦正式发布首款双滚刷双活水洗地机&#xff0c;集吸尘、洗拖、烘干于一体&#xff0c;双刷双喷淋一分钟洗地机1000次&#xff0c;可达10倍洁净效果&#xff01;该产品已正式在各大平台上开售&#xff0c;首发价2399元。 近年来&#xff0c;洗地机市…

每日自动化提交git

目前这个功能&#xff0c;有个前提&#xff1a; 这个git代码仓库&#xff0c;是一个人负责&#xff0c;所以不存在冲突问题 我这个仓库地址下载后的本地路径是&#xff1a;D:\Projects\Tasks 然后我在另外一个地方新建了一个bat文件&#xff1a; bat文件所在目录为&#xff1a…

吴恩达怒斥AI阴谋、Hinton自证清白!Lecun掀起图灵奖大战、哈萨比斯进行回怼!美国AI顶流圈乱象纪实…

大家好&#xff0c;我是夕小瑶科技说编辑王二狗&#xff0c;最近AI圈大瓜不断&#xff0c;对此我表示吃的很是辛苦&#x1f62d; 所以求大家帮我吃一些 &#x1f64f; 别只让我一个人吃&#xff01; 就在前天&#xff0c;Yann LeCun作为图灵奖得主率先吵了起来&#xff0c;事情…

2009-2023年上海中考英语作文题目、命题趋势和备考建议(资源)

前面的文章中&#xff0c;六分成长介绍了上海中考语文的作文特点和备考建议。今天为大家介绍上海中考英语的作文那些事。 总体上来说&#xff0c;中国的学生对于写作的有效训练还是比较少的&#xff0c;所以大家都比较担心考试的作文——无论是语文还是英语。这两项也是考试中…

2023年Q3户外装备市场行业分析报告(京东数据分析):同比增长7%,品牌化发展是核心

近年来&#xff0c;户外运动在我国不少地方蓬勃兴起&#xff0c;发展至今&#xff0c;户外运动早已不是聚焦专业领域的小众群体活动&#xff0c;现已发展成为当下热门的大众休闲活动&#xff0c;参与人群愈发广泛&#xff0c;而这股热潮也带动着相关产业的发展。 今年Q3&#x…

麻醉科常用评估量表汇总,建议收藏!

根据麻醉科医生的量表使用情况&#xff0c;笔者整理了10个麻醉科常用量表&#xff0c;可在线评测直接出结果&#xff0c;可转发使用&#xff0c;可生成二维码使用&#xff0c;可创建项目进行数据管理&#xff0c;有需要的小伙伴赶紧收藏&#xff01; 1.维持液体计算 维持液体是…