当前位置: 首页 > 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…...

探索双闭环直流调速系统的仿真之旅:从疑惑到理解

simulink双闭环直流调速系统matlab仿真在学习直流调速系统的过程中&#xff0c;双闭环控制总让我感到有些困惑。PID控制器的参数如何选择&#xff1f;电流环和速度环之间到底有什么联系&#xff1f;带着这些问题&#xff0c;我决定通过Simulink仿真来寻找答案。 一、搭建仿真模…...

Go网络编程nethttp包解析

Go语言凭借其简洁高效的特性&#xff0c;已成为现代网络编程的热门选择。其中&#xff0c;标准库中的net/http包为开发者提供了强大的HTTP服务端和客户端功能&#xff0c;极大简化了Web开发流程。本文将深入解析net/http包的核心特性&#xff0c;帮助开发者掌握构建高性能Web服…...

造相-Z-Image-Turbo 在计算机网络教学中的应用:可视化展示协议交互角色

造相-Z-Image-Turbo&#xff1a;让计算机网络协议“活”起来的教学新助手 每次讲到TCP三次握手、HTTP请求响应这些概念&#xff0c;看着台下学生迷茫的眼神&#xff0c;你是不是也感到头疼&#xff1f;协议栈、数据包、端口号&#xff0c;这些抽象的名词和冰冷的箭头图&#x…...

老旧电脑焕新:OpenClaw+GLM-4.7-Flash在4GB内存设备上的优化运行方案

老旧电脑焕新&#xff1a;OpenClawGLM-4.7-Flash在4GB内存设备上的优化运行方案 1. 为什么要在老旧电脑上部署AI助手&#xff1f; 去年整理书房时&#xff0c;我翻出一台2015年的MacBook Air&#xff0c;4GB内存的配置在当下连浏览器开几个标签页都卡顿。正当准备将它送进回收…...

熵权法背后的信息论:为什么你的特征权重计算总不准?

熵权法的信息论本质&#xff1a;从数学原理到权重计算的精准控制 当我们需要从海量数据中提取关键特征时&#xff0c;如何科学地确定每个特征的权重&#xff1f;熵权法作为一种客观赋权方法&#xff0c;其核心思想源自信息论中的熵概念。但许多实践者发现&#xff0c;直接套用标…...

从服务边界到性能边界:理解 ABAP CDS View 里的窄投影及其重要性

结论先讲清楚 在 ABAP CDS 语境里,很多开发者口中的 窄投影,本质上并不是一个独立的官方语法关键字,而是一种建模策略:在 CDS projection view 这一层,只暴露某个具体业务服务真正需要的那一小部分字段、关联、行为和注解,不把底层业务对象里所有能拿到的内容一股脑端出…...

AI 短剧创作卷疯了?这个平台让成本降 85%,单人也能做爆款

2025 年 AI 短剧赛道彻底火了&#xff01;日流水超 3200 万、抖音漫剧年播放量破 757 亿&#xff0c;这个背靠 AIGC 技术的新赛道&#xff0c;正在成为内容创作者的掘金新风口。但传统制作流程里的工具切换繁琐、团队协作低效、成本居高不下&#xff0c;却让很多创作者望而却步…...

OpenClaw监控告警:GLM-4.7-Flash任务异常自动通知设置

OpenClaw监控告警&#xff1a;GLM-4.7-Flash任务异常自动通知设置 1. 为什么需要监控告警系统 上周我部署了一个基于GLM-4.7-Flash的自动化日报生成任务&#xff0c;结果连续三天都没收到输出。检查后发现是模型服务意外重启导致任务中断——这种"静默失败"在自动化…...

BGP路由优化:配置、故障排除与网络性能提升

BGP路由优化&#xff1a;配置、故障排除与网络性能提升在复杂的网络环境中&#xff0c;尤其是在涉及多个自治系统&#xff08;AS&#xff09;互联互通的场景下&#xff0c;边界网关协议 BGP (Border Gateway Protocol) 作为互联网的关键路由协议&#xff0c;直接影响着网络稳定…...

OpenClaw+GLM-4.7-Flash:个人日程管理与智能提醒系统

OpenClawGLM-4.7-Flash&#xff1a;个人日程管理与智能提醒系统 1. 为什么需要AI日程管理助手 每天早上打开邮箱&#xff0c;总能看到十几封待处理的会议邀请&#xff1b;微信群里不断跳出的临时讨论需求&#xff1b;便签纸上随手记下的待办事项越积越多——这大概是我过去三…...