java EE初阶 — Synchronized 的原理

news2024/11/28 17:47:32

文章目录

  • 1. Synchronized 的优化操作
    • 1.1 偏向锁
    • 1.2 轻量级锁(自旋锁)
    • 1.3 重量级锁
  • 2. 其他的优化操作
    • 2.1 锁消除
    • 2.2 锁粗化
  • 3. 相关面试题

1. Synchronized 的优化操作


两个线程针对同一个对象加锁,就会产生阻塞等待。
Synchronized 内部其实还有一些优化机制,存在的目的就是为了让这个锁更加的高效好用。

JVM 将 synchronized 锁分为 无锁偏向锁轻量级锁重量级锁 状态。
会根据情况,进行依次升级。

1.1 偏向锁


进行加锁的时候,首先会进行到 偏向锁 的状态。

偏心锁并不是真正的加锁,而只是占个位置。有需要的时候再加速,没需要就不加了。

synchronized 加锁的时候,并不是真正的加锁,而是先是 偏向锁 状态,做个标记。
(这个过程非常轻量)如果整个使用锁的过程中,都没有出现锁竞争。在 synchronized 执行完之后
取消偏向锁即可。

但是,如果使用过程中,另一个也尝试加锁,在它加锁之前,迅速把偏向锁升级成真正的加锁状态,
另一个线程也就只能阻塞等待了。


就好比我和一个一个女生搞暧昧,但是又不和她确定关系。
当有一天,突然出现了另外一个男人,比我优秀还比我帅,我担心她被抢走就赶紧和她确定男女朋友关系,然后让她和之前的那个男人彻底断绝来往。

1.2 轻量级锁(自旋锁)


当 synchronized 发生锁竞争的时候,就会从 偏向锁 升级成 轻量级锁
此时,synchronized 相当于是通过自旋的方式来进行加锁的。(和 CAS 篇章伪代码一致)

CAS 文章:

https://blog.csdn.net/m0_63033419/article/details/128614745?spm=1001.2014.3001.5501

自旋操作是一直让 CPU 空转,比较浪费 CPU 资源。
因此此处的自旋不会一直持续进行,而是达到一定的时间/重试次数,就不再自旋了。
也就是所谓的 “自适应”。

如果要是很快锁被释放了,自旋还是很划算的,但是如果迟迟拿不到锁,一直自旋,那就不划算了。
synchronized 自旋不是无休止的自旋,自旋到一定程度之后就会再次升级为重量级锁。(挂机等待锁)

1.3 重量级锁


重量级锁 则是基于操作系统原生的 API 来进行加锁的。Linux 则提供了 mutex 一组 API 。
操作系统内核提供的加锁功能,这个锁会影响到线程的调度。

此时如果线程进行了重量级锁的加锁,并且发生锁竞争,此时线程就会被放到阻塞队列中,
暂时不参与 CPU 调度了。然后直到锁被释放了,这个线程才有机会被调度到并且有机获取到锁。


需要注意的是锁只能升级,不能降级。
除非是另外的一个锁对象,但是还是会重复上面的升级过程。

2. 其他的优化操作

2.1 锁消除


有些应用程序的代码中,用到了 synchronized,但其实没有在多线程环境下。(例如 StringBuffer)
StringBuffer 里的关键方法多带有 synchronized ,但是如果在单线程中使用 StringBuffer ,
加了 synchronized 锁也是白加,此时编译器就会直接把这些加锁操作给消除了。

2.2 锁粗化


指的是锁的粒度,synchronized 包含的代码越多,粒度就越粗;包含的代码越少,粒度就越细。

通常情况下,锁的粒度细一点比较好。加锁部分的代码是不能并发执行的,锁的粒度越细,能并发的代码就越多;反之就越少。

但是有些的情况下,锁的粒度粗一些会更好。
如果两次加锁之间的间隙非常小,此时还不如直接一次搞一把大锁直接搞定了。

3. 相关面试题


1、什么是偏向锁?

偏向锁不是真的加锁,而只是在锁的对象头中记录一个标记(记录该锁所属的线程)。
如果没有其他线程参与竞争锁,那么就不会真正执行加锁操作,从而降低程序开销。
一旦真的涉及到其他的线程竞争,再取消偏向锁状态,进入轻量级锁状态。


2、synchronized 实现原理 是什么?

参考上面的 synchronized 原理的全部内容。

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

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

相关文章

ubuntu docker elasticsearch kibana安装部署

ubuntu docker elasticsearch 安装部署 所有操作尽量在root下操作. 安装docker 1. 由于是基于宝塔面板安装的所以简答的点击操作即可完成安装. 我这里已经是正常的安装好了. 2.dcoker 镜像加速 https://cr.console.aliyun.com/cn-hangzhou/instances访问这个网址进去进行了…

快速上手Golang

自动推导赋值:自动推导赋值Go中 不同的数据类型不能进行计算对于浮点型默认都是float64 精确到小数点后15位单引号的 为字节类型 一位0~255的字符转换双引号的 为字符串类型多重赋值多重赋值a,b:1,2格式输出格式输出printf“%3d”三位整数,不满足三位时头部补空格“…

录制课程用什么软件好?3款超好用的课程视频录课软件

在互联网技术的飞速发展下,在线教学已经成为一种新型的教学形式,与传统的教学方法相比,在线教学具有低成本、突破地域、时间灵活、形式多样的教学方式。那录制课程用什么软件好?今天小编就跟大家分享3款超好用的课程视频录课&…

认真研究MySQL的主从复制(一)

【1】主从复制概述 ① 如何提升数据库并发能力 在实际工作中,我们常常将Redis作为缓存与MySQL配合使用,当有请求的时候,首先会从缓存中进行查找。如果存在就直接取出,如果不存在再访问数据库。这样就提升了读取的效率&#xff0…

中国数据库的诸神之战

作者 | 唐小引出品 | 《新程序员》编辑部“现在的数据库产品实在是太多了!”前几天,我和深耕数据库/大数据近 30 年的卢东明老师相聊时,他发出了这样的感慨。将包括 DB-Engines Ranking 以及国内数据库排行等在内的数据库产品列表进行汇总&am…

快速入门Freemarker模块引擎技术

1、 freemarker 介绍 ​ FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库&am…

采场的车辆管理及卸料点计数管理有哪些难题需要解决

近期,安环部检查采矿区域工程车辆驾驶人员情况时,发现有部分驾驶员及工作人员存在违规顶替情况,有非注册备案人员驾驶矿用工程车辆违规作业。为了进行统一有效的人员车辆管理,同时能监督安全员定期对采矿作业区进行安全巡查&#…

Camtasia Studio2023喀秋莎新增功能及电脑配置要求介绍

Camtasia Studio2023具有强大的视频播放和视频编辑功能,录制屏幕后,根据时间轴对视频剪辑进行各种标记、媒体库、画中画、画中画、画外音当然,也可以导入现有视频并对其进行编辑操作。编辑完成后,可以将录制的视频输出为最终的视频…

光伏废水深度除氟装置,用于高盐废水除氟的工艺

光伏行业废水根据生产产品可细分为单品硅生产线排水、多品硅生产线排水。其生产工序中有污水排放的工段主要是:制绒和清洗工段。废水中的主要污染物为由异丙醇引起的高浓度COD、氟离子及酸碱污染,其中以含异丙醇的废水一直是水处理中的难题。如果不对废水…

【自学Python】Python input()函数

Python input()函数 Python input()函数教程 在 Python 中,input() 函数用于获取用于的输入,并给出提示。input() 函数,总是返回 string 类型,因此,我们可以使用 input() 函数,获取用户输入的任何数据类型…

【C进阶】第十五篇——内存函数

memcpy - 内存拷贝1 函数介绍 模拟实现 memmove - 内存拷贝2 函数介绍 模拟实现 memcmp - 内存比较 memset - 内存设置 memcpy - 内存拷贝1 函数介绍 void *memcpy( void *dest, const void *src, size_t count );memcpy函数是一个用于拷贝两个不相关的内存块的函数。…

4-2文件管理-文件系统实现

文章目录一.文件系统层次结构二.文件系统的全局结构三.虚拟文件系统与文件系统挂载(安装)(一)虚拟文件系统(二)文件系统挂载(安装)一.文件系统层次结构 (1)用…

密码学_MD5算法

MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。 MD5算法具有以下特点&#xff1a…

php宝塔搭建部署实战易优cms皮具皮包手袋定制网站源码

大家好啊,我是测评君,欢迎来到web测评。 本期给大家带来一套php开发的易优cms皮具皮包手袋定制网站源码,感兴趣的朋友可以自行下载学习。 技术架构 PHP7.2 nginx mysql5.7 JS CSS HTMLcnetos7以上 宝塔面板 文字搭建教程 下载源码&a…

Java 日常开发记录

手动分页 非mybatis 自动分页 service 层 Overridepublic PageInfo<CfLogVo> cfLogList(CfLogQuery cfLogQuery) {if (StrUtil.isNotBlank(cfLogQuery.getRequest()) && cfLogQuery.getRequest().length() >100){throw new ServiceException("请求报文…

Flutter | 使用 typedef 让回调更优雅

今天来谈谈 Flutter 的 typedef。 一. 熟悉的 VoidCallback 之前看 setState 源码的时候&#xff0c;发现它的参数是 VoidCallback&#xff1a; void setState(VoidCallback fn) {}VoidCallback 其实是一个自定义类型的无参数无返回值的匿名函数&#xff1a; /// Signature…

mybatis之配置优化and映射器

环境配置&#xff1a; mybatis可以配置成适应多种环境&#xff0c;但是要记住&#xff0c;尽管可以配置多个环境&#xff0c;但每个SqlSessionFactory实例只能选择一种环境。 虽然&#xff0c;MyBatis 中有两种类型的事务管理器:type("[JDBC|MANAGED]"&#xff09;…

Web进阶:Day3 移动端特点、百分比布局、Flex布局、实战演练

Web进阶&#xff1a;Day3 Date: January 7, 2023 Summary: 移动端特点、百分比布局、Flex布局、实战演练 移动端特点 移动端和PC端网页不同点 PC端网页和移动端网页的有什么不同&#xff1f; PC屏幕大&#xff0c;网页固定版心 手机屏幕小&#xff0c; 网页宽度多数为100%…

【Docker】(五)使用bind mounts修改Docker容器中的Nginx配置

1.前言 本系列文章记录了从0开始学习Docker的过程&#xff0c;Docker系列历史文章&#xff1a; &#xff08;一&#xff09;基本概念与安装使用 &#xff08;二&#xff09;如何使用Docker发布一个SpringBoot服务 &#xff08;三&#xff09;使用registry远程镜像仓库管理镜像…

axios拦截器、ElementUI

一、axios拦截器 1、axios模块的作用 是对基于http请求的封装。在浏览器对异步请求对象XMLHttpRequest进行封装 2、拦截器 ​ &#xff08;1&#xff09;请求拦截器&#xff1a;对客户端发起的请求进行统一的前期处理&#xff08;token、时间戳、cookie等&#xff09; ​ …