ReentrantLock通过Condition实现锁对象的监视器功能

公平锁和非公平锁只有两处不同,总结:

1、非公平锁在调用 lock 后,首先就会调用 CAS 进行一次抢锁,如果这个时候恰巧锁没有被占用,那么直接就获取到锁返回了。
2、非公平锁在 CAS 失败后,和公平锁一样都会进入到 tryAcquire 方法,在tryAcquire方法中,如果发现锁这个时候被释放了(state == 0),
非公平锁会直接 CAS 抢锁,但是公平锁会判断等待队列是否有线程处于等待状态,如果有等待,则不去抢锁,乖乖排到后面。公平锁和非公平锁就这两点区别,如果这两次 CAS 都不成功,那么后面非公平锁和公平锁是一样的,都要进入到阻塞队列等待唤醒。
相对来说,非公平锁会有更好的性能,因为它的吞吐量比较大。
当然,非公平锁让获取锁的时间变得更加不确定,可能会导致在阻塞队列中的线程长期处于饥饿状态。

二、Condition

其中,Lock替代了 synchronized 方法和语句的使用,【Condition】 替代了 Object 【监视器】方法的使用

我们以往开发,需要用到锁, 并且要用到睡眠和唤醒就只有synchronized, 但是【ReentrantLock】也实现了,Lock实现了锁,Condition还实现了睡眠和唤醒的功能。
ConditionObject主要是为并发编程中的同步提供了等待通知的实现方式,可以在不满足某个条件的时候挂起线程等待。直到满足某个条件的时候在唤醒线程。

synchronized的缺点

1synchronizednotify() 方法一次只能唤醒一个线程,而且唤醒线程的方式是随机的,从处于等待集中随机选取一个线程唤醒。
并且是唤醒等待队列中优先级最高的线程。
2notify()可能会导致死锁,原因是notify唤醒了线程A,可能要获取的锁此时已经被别的线程获取了,那么线程A一直在阻塞,
而线程A获得锁,这个锁对应的阻塞队列里面的其他线程永远得不到执行。正确的使用场景是WaitSet中等待的条件是相同, 确保唤醒任意一个都能够执行后面的事项。 
如果被唤醒的线程无法正确处理,务必继续notify()下一个线程,并且自身要回到WaitSet等待集中。那就要用到下面2个方法,他们可以控制具体线程的唤醒和阻塞,但是不释放锁。
LockSupport.park(this) 阻塞,但是不释放锁。
LockSupport.unpark(thread对象)  唤醒指定的线程。
与之对应的还有下面的2个方法
Thread.sleep(n) 不会释放占有的锁,但是会让出cpu执行权,到时自动唤醒,然后抢cpu的执行权。
Object.wait(n) 会释放占有的锁,没传时间就一直睡眠,需要其他线程调用Object对象notify方法。加了时间自动醒,进到阻塞队列再来重新获取锁。object.wait和thread.wait区别
每个类都继承了Object类,Object有个非静态的方法wait,所以要调用wait必须先有实例对象,才能调用wait方法。
Thread类也继承了Object类。
只有object.wait这么调用的,没有见过thread.wait,因为调用wait方法,必须要持有这个对象的锁,不然会报错,我们要拿到一个对象的锁,
就要使用synchronized来锁住对象。 我们也不会把线程对象thread当做我们的并发锁,

三、synchronized加锁原理

每个对象都关联了一个监视器,线程可以对其进行【加锁和解锁】操作。在同一时间,只有一个线程可以拿到对象上的监视器锁。
如果其他线程在锁被占用期间试图去获取锁,那么将会【被阻塞】直到成功获取到锁。
同时,【监视器锁可以重入】,也就是说如果线程 T 拿到了锁,那么线程T可以在解锁之前重复获取锁;每次解锁操作会反转一次加锁产生的效果synchronized 代码块。synchronized(object) 在对某个对象上执行加锁时,会尝试在该对象的监视器上进行加锁操作,
只有成功获取锁之后,线程才会继续往下执行。线程获取到了监视器锁后,将继续执行 synchronized 代码块中的代码,如果代码块执行完成,
或者抛出了异常,线程将会自动对该对象上的【监视器执行解锁】操作。synchronized 作用于方法,称为同步方法。同步方法被调用时,会自动执行加锁操作,只有加锁成功,方法体才会得到执行。
如果被 synchronized 修饰的方法是实例方法,那么这个实例的监视器会被锁定。
如果是 static 方法,线程会锁住相应的 Class 对象的监视器。
方法体执行完成或者异常退出后,会自动执行解锁操作。

小知识点:对 【Class】加锁、对【对象】加锁,它们之间不构成同步。synchronized 作用于静态方法时是对 Class 对象加锁,作用于实例方法时是对实例加锁。
面试中经常会问到一个类中的两个 synchronized static 方法之间是否构成同步?构成同步。

【等待状态】是指进程由于某种条件不具备,在等待队列中排队,等待cpu对它进行调度。
【阻塞状态】可能是由于竞争共享资源的情况下,没有得到锁或信号量的条件不满足而在临界区之外被暂停执行了。

文章地址

Condition使用案例

CountDownLatch主要功能,是一个计数器,主要countDown()wait()方法1、一开始创建CountDownLatch对象,需要指定一个数字,这个数字和公平锁里面的state一样,比如100,就表示某个锁被重入了100次,
所以需要释放一百次,countDown就类似于释放一次锁的意思,所以countDown方法,要放在子线程里面执行,子线程完成一次任务,就减一。2、什么场景要调用wait()呢,比如启动服务,需要启动创建N个组件,创建了一个组件就countDown(),我们只需要在线程池外面wait就可以了,
就等status变成0就可以了,如果没有变成0,那么调用wait的线程就会【阻塞】,并且进到阻塞队列,为什么会进到阻塞队列,
因为假如这个CountDownLatch对象是多个线程共享,那么多个线程都想知道status什么时候变成0,所以只要是通过CountDownLatch调用wait那
么就会阻塞,那么多个线程阻塞总得排队,多个线程调用wait都有可能阻塞进到队列,那么什么时候唤醒这些阻塞队列,就是等state变成0,
然后通过自旋的方式,从阻塞队列里面把所有Node取出来,挨个唤醒。

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

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

相关文章

Postman的Cookie鉴权

近期在复习Postman的基础知识,在小破站上跟着百里老师系统复习了一遍,也做了一些笔记,希望可以给大家一点点启发。 一)什么是Cookie 定义:存储在客户端的一小段文本信息,格式为键值对的形式. 二&#xff09…

如何基于OpenCV和Sklearn算法库开展机器学习算法研究

大家在做机器学习或深度学习研究过程中,不可避免都会涉及到对各种算法的研究使用,目前比较有名的机器学习算法库主要有OpenCV和Scikit-learn(简称Sklearn),二者都支持各种机器学习算法,主要有监督学习、无监…

无重复字符的最长子串 Golang leecode_3

刚开始的思路,先不管效率,跑出来再说,然后再进行优化。然后就有了下面的暴力代码: func lengthOfLongestSubstring(s string) int {// count 用来记录当前最长子串长度var count int// flag 用来对下面两个 if 语句分流var flag …

Leetcode刷题详解——岛屿数量

1. 题目链接:200. 岛屿数量 2. 题目描述: 给你一个由 1(陆地)和 0(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上…

怎样正确做 Web 应用的压力测试?

面试的时候,很多后端或者QA的候选人都会跟我讲说有过压力测试的经验,但在我细问之后,极少有候选人能够把压力测试细节讲清楚。 这里整理一下我认为做压力测试时需要注意的一些细节。 1、环境 首先环境是非常重要的,需要尽可能跟…

Spring Data JPA where in 超过 1000 解决方案

解决方案: 当在Spring Data JPA中使用WHERE IN子句时,如果IN中的元素数量超过1000,可能会导致错误。这是由于一些数据库对IN子句中的元素数量有限制。为了解决这个问题,你可以采取以下解决方案: 分页查询&#xff1a…

汽车OBD2蓝牙诊断仪解决方案程序开发

1、因TL718已经为你建立了物理层、数据链层和部分应用层的协议,所以只要OBD2标准应用层协议文本,ISO15031-5 或 SAE J1979(这两个协议是相同的内容)。 2、TL718诊断接口 1 套或用TL718芯片自建电路。3、家用PC机电脑一台。4、安…

计算机网络——物理层-编码与调制(数字基带信号、模拟基带信号、码元、常用编码、基本调制方法、混合调制)

目录 编码与调制 数字基带信号 模拟基带信号 码元 常用编码 不归零编码 归零编码 曼彻斯特编码 差分曼彻斯特编码 编码习题 基本调制方法 调幅 调频 调相 混合调制 QAM-16 编码与调制 在计算机网络中,计算机需要处理和传输用户的文字、图片、音频…

深度学习AI识别人脸年龄

以下链接来自 落痕的寒假 GitHub - luohenyueji/OpenCV-Practical-Exercise: OpenCV practical exercise https://download.csdn.net/download/luohenyj/10993309 import cv2 as cv import time import argparsedef getFaceBox(net, frame, conf_threshold0.7):frameOpencvDn…

Vue3 自定义指令封装实现防抖 防止按钮暴力点击

本来项目前期没有做按钮防抖功能 快结束时才想起来 然后一个个写太慢了 然后就想着封装一下 新建 directive.js export default {//自定义节流操作preventReClick: {mounted(el, binding) {el.addEventListener(click, () > {if (!el.disabled) {el.disabled truesetTime…

Android 10.0 系统内存优化之修改dalvik虚拟机的内存参数

1.前言 在10.0的系统开发定制中,app应用也是运行在dalvik虚拟机上的,所以对于一些内存低的系统中,在某些大应用会出现耗内存 卡顿情况,这是系统分配的内存不够大,在进行耗内存的操作,就会出现频繁gc等等原因造成不流畅的现象,接下来就分析下 虚拟机分配内存的相关原理 …

结构工程师软件 Naviate Core MEP for Revit 3.4 Crk

Naviate Fabrication - 先进的建模和制造命令,可提高 VDC 设计师、细节设计师和承包商的生产力和收入。 Naviate MEP - 通过 MEP 工程师和设计师的建模和参数提高效率 导航架构 Naviate Architecture 完全集成到 Revit 平台中,增强了 BIM 提供的协作可能…

C++标准模板(STL)- 类型支持 (属性查询,获取类型的对齐要求)

类型特性 类型特性定义一个编译时基于模板的结构&#xff0c;以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为&#xff0c;除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实例…

使用JAVA pdf转word

使用spire.pdf 非常简单。 查看 https://mvnrepository.com/artifact/e-iceblue/spire.pdf 注意&#xff0c;这个包在 e-iceblue 下。 下面开始撸代码 先来pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://mav…

大数据-之LibrA数据库系统告警处理(ALM-12047 网络读包错误率超过阈值)

告警解释 系统每30秒周期性检测网络读包错误率&#xff0c;并把实际错误率和阈值&#xff08;系统默认阈值0.5%&#xff09;进行比较&#xff0c;当检测到网络读包错误率连续多次&#xff08;默认值为5&#xff09;超过阈值时产生该告警。 用户可通过“系统设置 > 阈值配置…

微服务架构演进

系统架构演变 没有最好的架构&#xff0c;只有最合适的架构&#xff1b;架构发展过程&#xff1a;单体架构》垂直架构》SOA 面向服务架构》微服务架构&#xff1b;推荐看看《淘宝技术这十年》&#xff1b; 单体架构 互联网早期&#xff0c;一般的网站应用流量较小&#xff0…

keepalived安装配置(服务器主备、负载均衡)

系统拓扑 安装keepalived 主备服务器上都需要安装 在线安装 yum install -y keepalived 离线安装 # todo 服务器准备 虚拟机ip&#xff1a;192.168.11.56 主服务器&#xff1a;192.168.11.53 备服务器&#xff1a;192.168.11.54 配置文件修改 keepalived安装之后&…

接口

文章目录 概述语法使用特性接口的继承抽象类和接口的区别 概述 电脑的USB口上&#xff0c;可以插&#xff1a;U盘、鼠标、键盘…所有符合USB协议的设备 电源插座插孔上&#xff0c;可以插&#xff1a;电脑、电视机、电饭煲…所有符合规范的设备 通过上述例子可以看出&#xff…

中断的分类、机理与嵌套:深入理解计算机系统的中断、陷入与异常

一、引言 在计算机科学和电子工程领域&#xff0c;中断、陷入和异常是操作系统和硬件设计中关键的概念。这些概念在处理多任务环境、实时系统以及调试问题等方面具有重要作用。本文将对这些概念进行详细的探讨&#xff0c;包括中断的分类、机理、嵌套&#xff0c;以及中断、陷…

【Rust】快速教程——从hola,mundo到所有权

前言 学习rust的前提如下&#xff1a; &#xff08;1&#xff09;先把Rust环境装好 &#xff08;2&#xff09;把VScode中关于Rust的插件装好 \;\\\;\\\; 目录 前言先写一个程序看看Rust的基础mut可变变量let重定义覆盖变量基本数据类型复合类型&#xff08;&#xff09;和 [ …