Java并发编程学习笔记:synchronized

Java并发编程学习笔记:synchronized

  • 一、synchronized关键字
    • 实例方法
    • 静态方法
    • 代码块
  • 二、底层原理
  • 三、锁的升级
    • 锁的状态
    • 锁升级

一、synchronized关键字

实例方法

作用在类的普通方法上,锁的是当前对象实例。构造方法本身是线程安全的,不能使用synchronized关键字修饰。

synchronized void function() {}

静态方法

作用在类的静态方法上,锁的是当前类class。

synchronized static void function() {}

代码块

作用在代码块上,锁的是指定的对象实例或者class。

synchronized (object) {}
synchronized (class) {}

二、底层原理

synchronized 关键字底层原理属于 JVM,个人感觉就是信号量和PV操作理论的实际应用。

synchronized 同步语句块的实现使用的是 monitorenter(指令指向同步代码块的开始位置)monitorexit (指令则指明同步代码块的结束位置)

  • 在执行monitorenter时,会尝试获取对象的锁,如果锁的计数器为 0 则表示锁可以被获取,获取后将锁计数器设为 1 也就是加 1。

  • 对象锁的的拥有者线程才可以执行 monitorexit 指令来释放锁。在执行 monitorexit 指令后,将锁计数器设为 0,表明锁被释放,其他线程可以尝试获取锁。

  • 如果获取对象锁失败,那当前线程就要阻塞等待,直到锁被另外一个线程释放为止。

synchronized 修饰的方法用到的是 ACC_SYNCHRONIZED 标识,该标识指明了该方法是一个同步方法,从而去执行相对应的同步方法。

使用synchronized修饰方法和代码块的本质都是对对象监视器 monitor 的获取,每个 Java 对象都可以关联一个 Monitor 对象,不加 synchronized 的对象不会关联监视器。

监视器的主要功能就是提供互斥访问、线程同步、等待与唤醒等机制,是实现信号量机制PV的核心。

三、锁的升级

锁的状态

无锁: 对于共享资源,不涉及多线程的竞争访问。

偏向锁: 在只有一个线程连续多次获取同一个锁对象时,JVM会将锁偏向于该线程。后续该线程进入同步块时,只需检查是否为偏向锁持有者即可,无需进行其他加锁动作。当其他线程尝试获取该锁时,偏向锁才会撤销并升级为轻量级锁或重量级锁。

轻量级锁: 当多个线程同时申请共享资源锁的访问时,这就产生了竞争,JVM尝试使用CAS操作来快速获得锁 (通过自旋的方式循环尝试获取锁,不阻塞线程采用循环等待)。如果自旋一定次数后仍无法获取到锁,则轻量级锁会膨胀成重量级锁,以防止无谓的CPU空转。

重量级锁: 如果共享资源锁已经被某个线程持有,此时是偏向锁状态,未释放锁前,再有其他线程来竞争时,则会升级到重量级锁。在轻量级锁状态多线程竞争锁时,也会升级到重量级锁。重量级锁由操作系统来实现,是传统的互斥锁的实现方式(确保一次只有一个线程可以访问临界区资源),所以性能消耗相对较高。

这4种级别的锁,在获取时性能消耗逐渐增加,也是锁升级的方向。

锁升级

锁升级是针对于synchronized锁在不同竞争条件下的一种优化,根据锁在多线程中竞争的程度和状态,可在无锁、偏向锁、轻量级锁和重量级锁之间进行流转,以降低获取锁的成本,提高获取锁的性能。锁升级的过程是不可逆的。

无锁到偏向锁: 当一个线程访问同步代码块并获取锁时,如果此时没有其他线程竞争该锁,那么JVM会把锁对象的标识符设置为这个获得锁的线程ID,并将锁对象的状态标记为偏向模式。持有偏向锁的线程在进入和退出同步代码块时,只需要检查当前线程ID是否与锁对象的标识符一致即可,无需执行CAS等复杂的操作。

JDK1.5版本后默认关闭了偏向锁。如果未开启偏向锁,线程访问共享资源则直接由无锁升级为轻量级锁。

偏向锁升级至轻量级锁: 当有第二个线程尝试获取已被偏向的锁时,偏向锁会撤销并升级为轻量级锁。在轻量级锁状态下,线程首先会在栈上创建一个“锁记录”结构(Lock Record),然后尝试通过CAS操作将其替换为对象头中的锁标志位。 如果CAS成功,表示线程获得了锁;如果失败,则表示存在其他线程的竞争,此时会自旋一段时间再次尝试获取锁。当自旋超过一定次数仍无法获取时,轻量级锁就会膨胀成重量级锁。

轻量级锁升级至重量级锁: 升级后,线程会被操作系统挂起,放入等待队列,由操作系统的线程调度器来决定何时唤醒线程继续争夺锁资源。

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

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

相关文章

海川润泽AI机器视觉仪系列产品,助推“人工智能+”打开新质生产力的大门

3月5日,第十四届全国人民代表大会第二次会议开幕。国务院总理李强在政府工作报告,提出大力推进现代化产业体系建设,加快发展新质生产力。深入推进数字经济创新发展,制定支持数字经济高质量发展政策,积极推进数字产业化…

零基础自学C语言|动态内存管理

✈为什么要有动态内存分配 我们已经掌握的内存开辟方式有: int a 0;//在栈空间上开辟四个字节char arr[10] { 0 };//在栈空间上开辟10个字节的连续空间但是上述的开辟空间的方式有两个特点: 空间开辟大小是固定的。数组在申明的时候,必须…

【开源】SpringBoot框架开发公司货物订单管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 客户管理模块2.2 商品维护模块2.3 供应商管理模块2.4 订单管理模块 三、系统展示四、核心代码4.1 查询供应商信息4.2 新增商品信息4.3 查询客户信息4.4 新增订单信息4.5 添加跟进子订单 五、免责说明 一、摘要 1.1 项目…

Cap2:Pytorch转TensorRT(上:Pytorch->ONNX)

文章目录 1、pytorch导出onnx模型2、使用onnxruntime推理onnx模型3、精度对齐4、总结 深度学习框架种类繁多,想实现任意框架之间的模型转换是一件困难的事情。但现在有一个中间格式ONNX,任何框架模型都支持转为ONNX,然后也支持从ONNX转为自身…

案例分析篇00-【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-先导篇)

专栏系列文章: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 案例分析篇01:软件架构设计考点架构风格及质量属性 案例分析篇11:UML设计考…

Java 常用注解

一、较不熟悉 1、@MappedJdbcTypes(JdbcType.VARCHAR) MyBatis 框架中的一个注解,用于指定某个字段或方法参数与数据库中的 JDBC 类型之间的映射关系。通常作用在实体类属性或者参数上。 如下标识username字段映射到数据库中的VARCHAR属性。 public interface UserMapper {@Se…

KY199 查找

描述: 输入数组长度 n 输入数组 a[1…n] 输入查找个数m 输入查找数字b[1…m] 输出 YES or NO 查找有则YES 否则NO 。 输入描述: 输入有多组数据。 每组输入n,然后输入n个整数,再输入m,然后再输入m个整数(1&…

疫情网课管理系统|基于springboot框架+ Mysql+Java+Tomcat的疫情网课管理系统设计与实现(可运行源码+数据库+设计文档+部署说明)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 ​编辑 学生功能模块 管理员功能 教师功能模块 系统功能设计 数据库E-R图设计 lun…

人工智能入门之旅:从基础知识到实战应用(五)

一、人工智能实战项目与案例分析 1. AI入门项目电影评论情感分析实战 典型的AI入门实战项目,比如电影评论情感分析,是一个非常适合初学者的项目,因为它简单易懂,同时涵盖了自然语言处理(NLP)领域的一些基…

Ubuntu上搭建TFTP服务

Ubuntu上搭建TFTP服务 TFTP服务简介搭建TFTP服务安装TFTP服务修改配置文件 重启服务 TFTP服务简介 TFTP是一个基于UDP协议实现的用于在客户机和服务器之间进行简单文件传输的协议,适用于开销不大、不复杂的应用场合。TFTP协议专门为小文件传输而设计,只…

虚拟游戏理财 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C 题目描述 在一款虚拟游戏中生活,你必须进行投资以增强在虚拟游戏中的资产以免被淘汰出局。 现有一家Bank,它提供有若干理财产品m,风险及…

line_profiler逐行分析代码时间

最近model训练有点瓶颈,GPU的利用率总是很低。所以看看能不能使用line_profiler来发现问题。 使用方式: 确保 line_profiler 正确安装: pip install line_profiler在需要分析的函数加上修饰器: from line_profiler import prof…

【PHP安全】PHP伪协议

PHP伪协议: file:// #访问本地文件系统http:// #访问HTTPs网址ftp:// #访问ftp URLphp:// #访问输入输出流zlib:// #压缩流data:// #数据(RFC 2397)ssh2:// #security shell2expect:// #处理交互式的流glob:// #查找匹配的文件路径phar:// #P…

33.使用ORDER BY排序

用ORDER BY子句排序行 ASC:升序排序,默认 DESC:降序排序 ORDER BY 子句在SELECT 语句的最后 在一个不明确的查询结果中排序返回的行。ORDER BY子句用于排序。如果使用了ORDER BY子句,它必须位于SQL语句的最后。 SELECT 语句的…

Siamese Network(孪生神经网络)详解

Siamese和Chinese有点像。Siam是古时候泰国的称呼,中文译作暹罗。Siamese也就是“暹罗”人或“泰国”人。Siamese在英语中是“孪生”、“连体”的意思,这是为什么呢?十九世纪泰国出生了一对连体婴儿,当时的医学技术无法使两人分离…

前端页面渲染机制

前端页面渲染机制是指在 web 开发中,浏览器如何将 HTML、CSS 和 JavaScript 转换为用户可视化的网页界面的过程。这个过程通常包括以下几个主要步骤: 加载 HTML: 首先,浏览器会获取 HTML 文件,并解析其结构。这个过程包括识别 HTM…

MySQL锁—全局锁、表级锁、行级锁详解

MySQL 锁 MySQL的锁按照锁的粒度可以分为全局锁、表级锁和行级锁。 一、全局锁 1. 概念 全局锁,是对整个数据库实例加锁,加锁后整个实例处于只读状态,后续的DML、DDL语句以及已经执行更新操作的事务提交语句都将被阻塞。 2. 应用场景 数据…

软件功能测试内容有哪些?湖南长沙软件测评公司分享

软件功能测试主要是验证软件应用程序的功能,且不管功能是否根据需求规范运行。是通过给出适当的输入值,确定输出并使用预期输出验证实际输出来测试每个功能。也可以看作“黑盒测试”,因为功能测试不用考虑程序内部结构和内部特性,…

MongoDB聚合运算符:$exp

文章目录 语法使用举例 $exp聚合运算符返回自然常数或欧拉数e的幂值&#xff08;次方&#xff09;的结果 语法 { $exp: <exponent> }<exponent>为指数&#xff0c;可以是任何数值表达式。 使用 如果参数为null或引用的字段不存在&#xff0c;$exp返回null&#…

【夏普利值——详细讲解】

夏普利值的介绍 沙普利值是合作博弈理论中的一个概念&#xff0c;由劳埃德-沙普利在1951年提出了这个概念&#xff0c;并因此在2012年获得了诺贝尔经济学奖。对于每个合作博弈&#xff0c;如联邦学习&#xff0c;可以将机构产生的模型的总提升在各个机构上形成一个有效的贡献分…