Java多线程(九)

目录

一、synchronized基本特点

二、synchronized加锁工作过程

2.1 无锁

2.2 偏向锁

2.3 轻量级锁

2.4 重量级锁

三、synchronized其他优化操作

3.1 锁消除

3.2 锁粗化


一、synchronized基本特点

  1. 开始是乐观锁,如果锁冲突频繁就会转换成悲观锁
  2. 开始是轻量级锁,如果锁被持有的时间变长就会升级成重量级锁
  3. 轻量级锁是通过自旋锁来实现的,重量级锁基于系统的互斥锁来实现的
  4. 是不公平锁(这里的不公平指的是不按照顺序执行线程,谁抢到算谁的)
  5. 是可重入锁(内部会通过计数器来记录加锁次数)
  6. 不是读写锁

二、synchronized加锁工作过程

由于synchronized具有多种特性,所以在加锁的过程中也是有不同的状态。Jvm将synchronized锁分为:无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁 这4种状态,会根据不同的场景依次进行升级。

2.1 无锁

无锁的解释很简单,线程可能加锁了,但是该线程还能没有被执行,此时synchronized就还处于无锁的状态。也就是说synchronized不会一开始就加锁,这也是效率提升的原因。

2.2 偏向锁

偏向锁不是真的加锁,只是对这个这个锁进行一个“偏向锁标记”,记录当前锁属于哪个线程。当后续有线程进行锁竞争的时候再升级为轻量级锁。

这里的这种做法就类似于单例模式中的懒汉模式,能不加锁就不加锁,尽量避免不必要的开销。但是还是会做好标记,在遇到锁竞争的时候方便加锁。

2.3 轻量级锁

随着其他线程进入竞争,偏向锁的状态解除,进入轻量级锁状态(自适应的自旋锁)。其他线程可能没有直接放弃,而是持续访问查看上个线程是否释放锁,如果释放就能第一时间拿到锁。但是这种情况下也有缺点,如果是上个线程持有的时间比较久,那么这样就会持续的消耗cpu资源。

2.4 重量级锁

如果锁竞争进一步激烈,自旋不能快速的获取到锁,那么synchronized就会膨胀为重量级锁。这里的重量级锁是指内核提供的mutex。

  • 执行加锁操作, 先进入内核态.
  • 在内核态判定当前锁是否已经被占用
  • 如果该锁没有占用, 则加锁成功, 并切换回用户态.
  • 如果该锁被占用, 则加锁失败. 此时线程进入锁的等待队列, 挂起. 等待被操作系统唤醒.
  • 经历了一系列的沧海桑田, 这个锁被其他线程释放了, 操作系统也想起了这个挂起的线程, 于是唤醒这个线程, 尝试重新获取锁.

三、synchronized其他优化操作

3.1 锁消除

这里的锁消除指的是当代码中加了synchronized锁但是并没有多线程,这里的编译器+Jvm就会直接将锁进行消除。但是并不是所有的场景编译器+Jvm都会进行这种优化,所以在编写代码的过程中还是需要自己编写的规范,不要过度依靠外物。

3.2 锁粗化

首先要了解一下这里的“粗”是指的什么,这里“粗”指的是synchronized中执行代码的多少,如果一段代码中多次出现加锁解锁,编译器+Jvm就会自动执行锁的粗化。

 

举个例子理解锁粗化:

滑稽老哥当了领导, 给下属交代工作任务:
方式一:
打电话, 交代任务1, 挂电话.
打电话, 交代任务2, 挂电话.
打电话, 交代任务3, 挂电话.
方式二:
打电话, 交代任务1, 任务2, 任务3, 挂电话.
显然, 方式二是更高效的方案.

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

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

相关文章

【java】mybatis-plus代码生成

正常的代码生成这里就不介绍了。旨在记录实现如下功能: 分布式微服务环境下,生成的entity、dto、vo、feignClient等等api模块,需要和mapper、service、controller等等分在不同的目录生成。 为什么会出现这个需求? mybatis-plus&am…

概率论:多维随机变量及分布

多维随机变量及分布 X X X为随机变量, ∀ x ∈ R , P { X ≤ x } F ( x ) \forall x\in R,P\{X\le x\}F(x) ∀x∈R,P{X≤x}F(x) 设 F ( x ) F(x) F(x)为 X X X的分布函数,则 (1) 0 ≤ F ( x ) ≤ 1 0\le F(x)\le1 0≤F(x)≤1 &am…

赛码网-triangle(dp) 100%AC代码(C)

———————————————————————————————————— ⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大三学生。 ⏩最近在准备秋招,一直在练习编程。 ⏩本篇文章对赛码网的01串的魔法 题目做…

【积水成渊】CSS磨砂玻璃效果和渐变主题色文字

大家好,我是csdn的博主:lqj_本人 lqj_本人_python人工智能视觉(opencv)从入门到实战,前端,微信小程序-CSDN博客 最新的uniapp毕业设计专栏也放在下方了: https://blog.csdn.net/lbcyllqj/category_12346639.html?spm1…

Android AlertDialog标题居中

网上很多做法都是使用setCustomTitle方法实现的,我偏不,因为我已经找到了标题的textView了: 在show了之后可以拿到标题(注意一定是show之后才能拿得到,create之后拿也是空的): TextView title…

优思学院|6西格玛标准值水平是多少?

在质量管理和统计学领域,"6西格玛" 是一个重要的概念,它与产品和流程的质量有着密切的关系。本文将解释"6西格玛"标准值水平是什么,以及它在各个行业中的应用。 什么是6西格玛标准值水平? 理解西格玛 西格…

《练习100》86~90

题目86 # 生成一个包含20个随机整数(100以内)的列表,对其中偶数索引(下标)的数据进行降序排列,奇数索引的元素不变 import random list1 [random.randint(0,100) for _ in range(20)] list2 list1[::2] …

非科班出身的人想要顺利地转型成为编程领域的专业人士的建议

目录 1、具体方法2、成功案列 非科班想要丝滑转码,可以参考下述步骤: 1、具体方法 了解想要从事的领域:比如前端开发、数据分析、产品经理等。通过互联网进行调查,了解这些领域的职责、技能需求、发展前景等。学习基础知识&#…

TextBrewer:融合并改进了NLP和CV中的多种知识蒸馏技术、提供便捷快速的知识蒸馏框架、提升模型的推理速度,减少内存占用

TextBrewer:融合并改进了NLP和CV中的多种知识蒸馏技术、提供便捷快速的知识蒸馏框架、提升模型的推理速度,减少内存占用 TextBrewer是一个基于PyTorch的、为实现NLP中的知识蒸馏任务而设计的工具包, 融合并改进了NLP和CV中的多种知识蒸馏技术&#xff0…

一键登录助力用户转化率稳步上升

一键登录是什么? 本机号码一键登录验证是一种登录认证方式,通过获取用户手机上的本机号码来验证用户身份,从而实现快捷登录和简化登录流程的目的。 在使用一键登录时,首先需要用户在登录页面选择使用本机号码一键登录&#xff0c…

【Spring Boot】拦截器与统一功能处理

博主简介:想进大厂的打工人博主主页:xyk:所属专栏: JavaEE进阶 上一篇文章我们讲解了Spring AOP是一个基于面向切面编程的框架,用于将某方面具体问题集中处理,通过代理对象来进行传递,但使用原生Spring AOP实现统一的…

平板选择什么电容笔比较好?ipad手写笔推荐品牌

在现在的生活上,有了iPad平板,一切都变得简单了许多,也让我们的学习以及工作都更加的便利。这其中,电容笔就起到了很大的作用,很多人都不知道,到底要买什么牌子的电容笔?哪些电容笔的性价比比较…

【C语言】11-三大结构之循环结构-2

1. 改变循环的状态 1.1 break 语句 break 语句在之前 switch 语句的学习中已经使用过了,它是用来退出 switch 语句的。在介绍控制语句时也提到了 break 语句可以和 switch 语句搭配使用以及退出循环,在这里我们将会正式学习使用 break 语句退出循环的用法 在之前的例子中,…

myql驱动升级flowable项目启动报错

最近系统升级需要将mysql的驱动升到8.0.27,升级后启动项目发现涉及到工作流的项目报错。Caused by: java.lang.ClassCastException: java.time.LocalDateTime cannot be cast to java.lang.String。报错信息是类型转换异常,我们找到报错的代码。这是因为…

CentOS7 启动谷歌浏览器 java+Selenium+chrome+chromedriver

前言:自己想使用该技术实现自动化抓取音乐,目前在window上运行成功,需要在Linux Centos服务上跑,配置上出现了许多问题,特此记录。 参考文档:CentOS7 安装Seleniumchromechromedriverjava_远方丿的博客-CSD…

后端开发7.轮播图模块【mongdb开发】

概述 轮播图模块数据库采用mongdb开发 效果图 数据库设计 创建数据库 use sc; 添加数据 db.banner.insertMany([ {bannerId:"1",bannerName:"商城轮播图1",bannerUrl:"http://xx:8020/img/轮播图/shop1.png"}, {bannerId:"2"…

篇十一:享元模式:共享细粒度对象

篇十一:“享元模式:共享细粒度对象” 设计模式是软件开发中的重要工具,享元模式(Flyweight Pattern)是结构型设计模式的一种。享元模式旨在通过共享细粒度的对象,减少内存消耗和提高性能。在设计模式学习中…

深入学习 Redis - 主从结构配置、流程、底层原理(全网最详细)

目录 前言 一、主从模式 1.1、概述 1.2、配置 redis 主从结构 1.2.1、复制配置文件,修改 1.2.2、配置主从结构 1.2.3、启动 redis 服务 1.2.4、查看复制状态 1.3、slaveof 命令 1.3.1、断开主从复制关系 1.3.2、切换主从复制关系 1.3.3、只读 1.3.4、网…

C语言——自定义类型详解[结构体][枚举][联合体]

自定义类型详解 前言:一、结构体1.1结构体的声明1.2结构体内存对齐1.3位段(位域) 二、枚举2.1枚举类型的定义2.2枚举类型的优点2.3枚举的使用 三、联合体3.1联合体类型的定义3.2联合体的特点3.3联合体大小的计算 前言: 我打算把结…

solr迁移到另一个solr中(docker单机)

背景介绍 solr数据迁移,或者版本升级,需要用到迁移,此处记录一下迁移方法以及过程中遇到的问题。我这边使用的是docker环境,非docker部署的应该也是一样的。 solr部署教程 准备工作 ● solrA 版本: 8.11.2 (已有so…