当前位置: 首页 > news >正文

【并发编程】 synchronized的普通方法,静态方法,锁对象,锁升级过程,可重入锁,非公平锁

目录

1.普通方法

2.静态方法

3.锁对象

4.锁升级过程

5.可重入的锁

6.不公平锁

非公平锁的 lock 方法:


1.普通方法


将synchronized修饰在普通同步方法,那么该锁的作用域是在当前实例对象范围内,也就是说对于 SyncDemosd=newSyncDemo();这一个实例对象sd来说,多个线程访问access方法会有锁的限制。如果access已经有线程持有了锁,那这个线程会独占锁,直到锁释放完毕之前,其他线程都会被阻塞

public SyncDemo{Object lock =new Object();//形式1public synchronized void access(){//}//形式2,作用域等同于形式1public void access1(){synchronized(lock){//}}//形式3,作用域等同于前面两种public void access2(){synchronized(this){//}}
}


2.静态方法


修饰静态同步方法或者静态对象、类,那么这个锁的作用范围是类级别。举个简单的例子,

SyncDemo sd=SyncDemo();
SyncDemo sd2=new SyncDemo();} 


两个不同的实例sd和sd2, 如果sd这个实例访问access方法并且成功持有了锁,那么sd2这个对象如果同样来访问access方法,那么它必须要等待sd这个对象的锁释放以后,sd2这个对象的线程才能访问该方法,这就是类锁;也就是说类锁就相当于全局锁的概念,作用范围是类级别。

这里抛一个小问题,大家看看能不能回答,如果不能也没关系,后面会讲解;问题是如果sd先访问access获得了锁,sd2对象的线程再访问access1方法,那么它会被阻塞吗?

public SyncDemo{static Object lock=new Object();//形式1public synchronized static void access(){//}//形式2等同于形式1public void access1(){synchronized(lock){//}}//形式3等同于前面两种public void access2(){synchronzied(SyncDemo.class){//}}
}


3.锁对象


普通同步方法,锁是当前实例对象。比如:

public synchronized void doLongTimeTaskC() {}


4.锁升级过程


无锁——》偏向锁——》轻量级锁——》重量级锁——》GC锁

5.可重入的锁


可重入的含义:指的是同一个线程获得锁之后,再不释放锁的情况下,可以直接再次获取到该锁

@Slf4j
public class SynReentrantDemo {public static void main(String[] args) {Runnable sellTicket = new Runnable() {@Overridepublic void run() {synchronized (this) {String name = Thread.currentThread().getName();log.info("我是run,抢到锁的是{}", name);test01();} //正常来说走出临界区(这个括号)才会释放锁,但是再没走出之前,又进入test01,//而test01需要和本方法一样的锁//如果不可重入的话,就将出现死锁了-->即test01方法等着释放锁,而run方法又不会释放锁//因此synchronized只有可以在不释放run方法的锁的情况下,又再次获得该锁才不会有问题}public void test01() {synchronized (this) {String name = Thread.currentThread().getName();log.info("我是test01,抢到锁的是{}", name);}}};new Thread(sellTicket).start();new Thread(sellTicket).start();}
}


首先应该知道synchronized锁的并不是同步代码块,而是锁对象关联的一个monitor对象(在java中每一个对象都会关联一个monitor对象),而这个对象里有一个变量叫recursions — 中文是递归的意思(我想大概是因为递归的时候发生可重入的几率应该是最大的,所以才用这个当变量名的吧),其实可以将它简单理解为一个计数器。

以上面的栗子为例:

(1)当线程1抢到run方法的执行权即抢到锁时,这个recursions的值就变为了1;
(2)线程1接着运行并进入test01方法后,发现还是线程1且还是要this这把锁,就将recursions的值再+1;
(3)当线程1,执行完test01方法时,recursions的值又-1
(4)执行完run方法时recursions的值又-1,就变为了0,也就是表示线程1已经释放了this锁。
(5)之后其他线程就可以继续抢this锁了。
 

6.不公平锁


非公平锁的 lock 方法:

static final class NonfairSync extends Sync {final void lock() {if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}// AbstractQueuedSynchronizer.acquire(int arg)public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);}
}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) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;
}


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

非公平锁在调用 lock 后,首先就会调用 CAS 进行一次抢锁,如果这个时候恰巧锁没有被占用,那么直接就获取到锁返回了。
非公平锁在 CAS 失败后,和公平锁一样都会进入到 tryAcquire 方法,在 tryAcquire 方法中,如果发现锁这个时候被释放了(state == 0),非公平锁会直接 CAS 抢锁,但是公平锁会判断等待队列是否有线程处于等待状态,如果有则不去抢锁,乖乖排到后面。
公平锁和非公平锁就这两点区别,如果这两次 CAS 都不成功,那么后面非公平锁和公平锁是一样的,都要进入到阻塞队列等待唤醒。

相对来说,非公平锁会有更好的性能,因为它的吞吐量比较大。当然,非公平锁让获取锁的时间变得更加不确定,可能会导致在阻塞队列中的线程长期处于饥饿状态。
 

相关文章:

【并发编程】 synchronized的普通方法,静态方法,锁对象,锁升级过程,可重入锁,非公平锁

目录 1.普通方法 2.静态方法 3.锁对象 4.锁升级过程 5.可重入的锁 6.不公平锁 非公平锁的 lock 方法&#xff1a; 1.普通方法 将synchronized修饰在普通同步方法&#xff0c;那么该锁的作用域是在当前实例对象范围内,也就是说对于 SyncDemosdnewSyncDemo();这一个实例对象…...

jQuery 删除元素 —— W3school 详解 简单易懂(十四)

通过 jQuery&#xff0c;可以很容易地删除已有的 HTML 元素。 删除元素/内容 如需删除元素和内容&#xff0c;一般可使用以下两个 jQuery 方法&#xff1a; remove() - 删除被选元素&#xff08;及其子元素&#xff09;empty() - 从被选元素中删除子元素 jQuery remove() 方…...

在 Linux 上搭建 Java 环境

目录 一、安装jdk 1. 挑选 jdk 版本 2. 安装 3. 验证 jdk 二、安装tomcat 1. 下载压缩包 2. 上传压缩包给 Linux &#xff08;需要用到 rz 命令&#xff09; 3. 解压压缩包&#xff08;需要用到 unzip&#xff09; 4. 进入 bin 目录 5. 给启动脚本增加可执行权限 6. 启…...

深度学习-Pytorch如何保存和加载模型

深度学习-Pytorch如何保存和加载模型 用pytorch构建模型&#xff0c;并训练模型&#xff0c;得到一个优化的模型&#xff0c;那么如何保存模型&#xff1f;然后如何又加载模型呢&#xff1f; pytorch 目前在深度学习具有重要的地位&#xff0c;比起早先的caffe&#xff0c;te…...

2.数据结构 顺序表(自留笔记)

文章目录 一.静态顺序表&#xff1a;长度固定二.动态顺序表1.下面证明原地扩容和异地扩容代码如下&#xff1a;2.下面是写一段Print&#xff0c;打印数字看看&#xff1a;3.头插4.尾删5.头删6.越界一定会报错吗7.下标插入8.下标删除9.查找数字10.应用&#xff1a;利用顺序表写一…...

将python打包成exe文件

将python打包成exe文件 文章目录 将python打包成exe文件1.安装PyInstaller2.配置pyinstaller到环境变量3.打包 以上一篇文章&#x1f517;用python删除重复文件并放入回收站为例&#xff0c;演示了如何用python写一个删除重复文件并放入回收站的功能代码&#xff0c;但是每次都…...

大数据处理,Pandas与SQL高效读写大型数据集

大家好&#xff0c;使用Pandas和SQL高效地从数据库中读取、处理和写入大型数据集&#xff0c;以实现最佳性能和内存管理&#xff0c;这是十分重要的。 处理大型数据集往往是一项挑战&#xff0c;特别是在涉及到从数据库读取和写入数据时。将整个数据集加载到内存中的传统方法可…...

【2024年5月备考新增】《软考高项论文专题 (2)论文背景(合集)》

1 论文的项目背景 1.1 论文写法 段落字数 - 正文全部字数不少于2000字孙悟空大闹天宫,被如来镇压,唐僧收服孙悟空,开始去西天取经。背景500字因为路途遥远,所以需要九九八十一难,才能取得正经。过渡段150字第一难、第二难 … 第八十一难过程1300字取得正经,唐僧只受了八…...

Mysql复习1--理论基础+操作实践--更新中

Mysql 索引索引的分类索引失效sql优化 删除数据库数据恢复 索引InnoDB引擎MyISAM引擎Memory引擎Btree索引支持支持支持hash索引不支持不支持支持R-tree索引不支持支持不支持Full-text索引5.6版本以后支持支持不支持 索引 解释说明: 索引指的是帮助mysql高效的获取数据的结构叫…...

微信小程序打卡定位实现方案

1背景 业务场景是考勤打卡,在考勤打卡这个业务场景中有两个关键技术点:定位和人员识别。用户界面初步确定是用微信小程序来实现,本文就定位问题做了技术上的调研。 2调研内容 平台注意事项 获取位置 选择位置 查看位置 距离计算 定位精度 防作弊 Demo 3调研结果 3.1平台注…...

小迪安全23WEB 攻防-Python 考点CTF 与 CMS-SSTI 模版注入PYC 反编译

#知识点&#xff1a; 1、PYC 文件反编译 2、Python-Web-SSTI 3、SSTI 模版注入利用分析 各语言的SSIT漏洞情况&#xff1a; SSIT漏洞过程&#xff1a; https://xz.aliyun.com/t/12181?page1&time__1311n4fxni0Qnr0%3DD%2FD0Dx2BmDkfDCDgmrYgBxYwD&alichlgrefhtt…...

计算机毕业设计 基于SpringBoot的律师事务所案件管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…...

如何使用宝塔面板配置Nginx反向代理WebSocket(wss)

本章教程&#xff0c;主要介绍一下在宝塔面板中如何配置websocket wss的具体过程。 目录 一、添加站点 二、申请证书 三、配置代理 1、增加配置内容 2、代理配置内容 三、注意事项 一、添加站点 二、申请证书 三、配置代理 1、增加配置内容 map $http_upgrade $connection_…...

vulhub之redis篇

CVE-2022-0543 | redis的远程代码执行漏洞 简介 CVE-2022-0543 该 Redis 沙盒逃逸漏洞影响 Debian 系的 Linux 发行版本,并非 Redis 本身漏洞, 漏洞形成原因在于系统补丁加载了一些redis源码注释了的代码 原理分析 redis一直有一个攻击面,就是在用户连接redis后,可以通过ev…...

Lua简介和应用场景介绍

Lua 的介绍 起源&#xff1a;Lua 于 1993 年在巴西里约热内卢的天主教大学&#xff08;PUC-Rio&#xff09;由 Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo 开发。 设计目的&#xff1a;Lua 设计的主要目标是为了嵌入到其他应用程序中&#xff0c;…...

【手写数据库toadb】10 开发数据库内核开发阶段-数据库模型

数据库内核模型介绍 ​专栏内容: 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方…...

02-Redis持久化、主从与哨兵架构详解

文章目录 Redis持久化RDB快照&#xff08;snapshot&#xff09;bgsave的写时复制(COW)机制AOF&#xff08;append-only file&#xff09;AOF重写RDB 和 AOF &#xff0c;我应该用哪一个&#xff1f; Redis 4.0 混合持久化Redis数据备份策略&#xff1a; Redis主从架构redis主从…...

无刷电机篇(一)直流无刷电机(BLDC)介绍

目录 01 直流无刷电机介绍 直流无刷电机内部结构 转子描述 定子描述 02 直流无刷电机分类 直流无刷电机分类描述 内、外转子电机描述 内、外转子电机区别 03 直流无刷电机参数 无刷电机参数 04 文章总结 大家好&#xff0c;这里是程序员杰克。一名平平无奇的嵌入式软…...

【GitHub项目推荐--不错的Flutter项目】【转载】

01 可定制的图表库 FL Chart是一个高度可定制的 Flutter 图表库&#xff0c;支持折线图、条形图、饼图、散点图和雷达图 。 项目地址&#xff1a;https://github.com/imaNNeoFighT/fl_chart LineChart BarChart PieChart Sample1 Sample2 Sample3 …...

Unity UnityWebRequest 向php后端上传图片文件

之前测试功能写过一次&#xff0c;因为代码忘记保存&#xff0c;导致真正用到的时候怎么也想不起来当初怎么写的了&#xff0c;复现后还是写个文章记录一下&#xff0c;省的下次再忘记。 php后端 /*** 图片保存到本地*/ public function uploadLocalImage() {try {$img $thi…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...