synchronized优化原理

news2024/10/6 22:22:28

文章目录

  • 一、Monitor
    • 1.1 Monitor结构
  • 二、轻量级锁
  • 三、锁膨胀
  • 四、自旋优化
  • 五、偏向锁


一、Monitor

Monitor的工作原理也是synchronized底层原理
每个Java对象都可以关联一个Monitor对象,如果使用synchronized给对象上锁之后,该对象头的MarkWord中就被设置指向Monitor对象的指针

1.1 Monitor结构

在这里插入图片描述

  1. 当多个线程来执行synchronized临界区代码时,若Thread2抢占到了使用权,那么Monitor对象中的Owner就指向Thread2
  2. 其他线程执行到synchronized时,发现obj已经关联了一个Monitor锁,查看Monitor锁的Owner有没有上锁,那么此时Monitor中的Owner是指向Thread2的,所以其他线程获取不到锁,那么获取不到锁的线程会与Monitor锁中的EntryList(可以把EntryList理解为等待队列)进行关联
  3. 当Monitor锁中Owner的Thread2线程将synchronized临界区代码执行完毕时,那么Monitor锁中Owner就空余出来,并且会通知Monitor锁中EntryList中的等待线程,唤醒等待线程后会去竞争,去竞争synchronized临街区代码的执行权,并且将获取到synchronized临街区代码的执行权的线程放入Monitor锁中的Owner

二、轻量级锁

轻量级锁的使用场景:如果一个对象虽然有多线程访问,但多线程访问的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化
轻量级锁对使用者是透明的,即语法仍然是synchronized

假设有两个方法同步块,利用同一个对象加锁

static final Object obj=new Object();
public static void method1(){
	synchronized(obj){
		//同步块A
		method2();
	}
	
}
public static void method2(){
	synchronized(obj){
		//同步块B

	}
}
  1. 创建锁记录(Lock Record)对象,它是JVM层面的,每个线程的栈帧都会包含一个锁记录的结构,内部可以存储锁定对象的Mark Word
    状态00 可以理解为 轻量级锁
    状态01 可以理解为 正常状态(未加锁)
    在这里插入图片描述

  2. 当线程T0执行到method1方法给对象上锁后,让T0线程中的Object reference指向锁对象,并尝试CAS替换Object中的Mark Word,将Mark Word的值存入T0线程中的锁记录
    状态00 可以理解为 轻量级锁
    状态01 可以理解为 正常状态(未加锁)
    在这里插入图片描述

  3. 如果T0线程CAS替换成功,Object对象头中存储了T0线程的锁记录地址和状态00,表示由该线程给对象加锁,如图

    状态00 可以理解为 轻量级锁
    在这里插入图片描述

  4. 如果第3步CAS失败,有两种情况
    4.1 如果是其他线程已经持有了该Object的轻量级锁,这时表明有竞争,进入锁膨胀过程
    4.2 如果是自己执行了synchronized锁重入(可以理解为加锁的方法1,又调用了加锁的方法2,加锁的是同一个obj),那么再添加一条Lock Record作为重入的计数
    在这里插入图片描述

  5. 当退出synchronized代码块(解锁时),如果T0线程有取值为null锁记录,表示有重入,这时重置锁记录,表示重入计数减一
    在这里插入图片描述

  6. 退出synchronized代码块(解锁时)锁记录的值不为null,这时T0线程使用CASMark Word的值恢复给Object对象头
    6.1 成功,则解锁成功
    6.2 失败,说明轻量级锁进行了锁膨胀或已经升级为重量级锁,进入重量级锁解锁流程

三、锁膨胀

如果在尝试加轻量级锁的过程中CAS操作无法成功,这是一种情况就是有其他线程为此对象加上了轻量级锁(有竞争),这时需要进行锁膨胀,将轻量级锁变为`重量级锁``

static Object obj=new Object();
public static void method1(){
	synchronized(obj){
		//同步块
	}
	
}
  1. T1线程进行轻量级加锁时,T0线程已经对该对象加了轻量级锁
    此时Object中Mark Word的状态是10,代表的是重量级锁
    在这里插入图片描述
  2. 这时T1加轻量级锁失败,进入膨胀锁流程
    2.1 即为Object对象申请Monitor锁,让Object指向重量级锁地址
    2.2 然后自己进入Monitor的EntryList变成blocked阻塞状态
    在这里插入图片描述
  3. 当T0线程退出同步块解锁时(此时T0线程给对象加的是轻量级锁),使用CAS将Mark Word的值恢复给Object的对象头,失败。这时会进入重量级解锁流程,即按照Monitor地址找到Monitor对象,设置Owner为null,唤醒EntryList中的blocked线程

四、自旋优化

  1. 自旋成功情况:重量级锁竞争的时候,还可以采用CAS自旋来进行优化,如果当前线程自旋成功(即这时候持锁线程已经退出了同步块,释放了锁),这时当前线程就可以避免阻塞
  2. 自旋失败情况:若线程执行synchronized同步块迟迟不解锁,B线程自旋重试几次之后,没有获取到锁,那么B线程就会进入Monitor的EntryList进入变成blocked状态

五、偏向锁

轻量级锁没有竞争时(就自己这个线程),每次重入仍然需要执行CAS操作。在Java6中引入了偏向锁来进一步优化:只有第一次使用CAS将线程ID设置到Object的Mark Word头,之后发现这个线程ID是自己的就表示没有竞争,不用重新CAS。以后只要不发生竞争,这个对象就归该线程所有

static final Object obj=new Object();
public static void method1(){
	synchronized(obj){
		//同步块A
		method2();
	}
	
}
public static void method2(){
	synchronized(obj){
		//同步块B
		method3();
	}
}
public static void method3(){
	synchronized(obj){
		//同步块C
		
	}
}

图解:当没有竞争时,T0线程执行m1方法执行synchronized(obj),会将ThreadID替换Obejct对象头中的MarkWord,m1又调用了m2方法,m2执行synchronized(obj),会去检查Object对象头中的ThreadID是否是自己当前这个线程,m2又调用了m3方法,m3执行synchronized(obj),会去检查Object对象头中的ThreadID是否是自己当前这个线程,则就不需要进行CAS尝试替换
在这里插入图片描述

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

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

相关文章

怎样从“点点点”进阶到自动化测试?

为什么要学习自动化测试 在讨论这个问题之前,先来聊一下测试人员的职业发展路线,无非就是两条,技术路线和管理路线,技术路线一般就是功能测试(60%)-->自动化测试(25%)-->测试…

fio引发的一些问题

fio引发的一些问题 奇怪的255扇区在nvme驱动中插入打印语句直接编译模块加载源码编译内核 查找内核源码 奇怪的255扇区 由于块设备驱动项目需要测试读写速度,故使用fio工具,没想着深入了解,简单测个速就可以 使用tldr命令得到测试磁盘读写的…

linux内核篇-文件系统(硬盘、虚拟文件系统、文件缓存)

文件系统的意义 之前说的都是在进程在物理内存保存的数据,内存就像一个纸箱子,仅仅是一个暂存数据的地方,而且空间有限。如果我们想要进程结束之后,数据依然能够保存下来,就不能只保存在内存里,而是应该保存…

Nacos-04-@RefreshScope自动刷新原理

Nacos动态刷新原理 Nacos做配置中心的时候,配置数据的交互模式是有服务端push推送的,还是客户端pull拉取的? 短轮询 不管服务端的配置是否发生变化,不停发起请求去获取配置,比如支付订单场景中前端JS不断轮询订单支…

hadoop启动,缺少RM的进程:Error starting ResourceManager【已解决】

Error starting ResourceManager【已解决】 现象解决思路报错内容解决总结 现象 Hadoop启动后 执行jps 查看进程,缺少了 ResourceManager 解决思路 start-all.sh分别会有五个日志产生 缺少哪个进程,就去看谁的日志 报错内容 resourcemanager的log文…

基于 Linux 下的生产者消费者模型

目录 传统艺能😎概念😘特点😍优点😁基于阻塞队列的生产者消费者模型🤣模拟实现😂基于计算任务的生产者消费者模型👌 传统艺能😎 小编是双非本科大二菜鸟不赘述,欢迎米娜…

chatgpt赋能Python-python3_date

Python 3 Date介绍 Python 3是一种非常流行的编程语言,其中涉及到日期处理的功能非常强大。Python 3支持处理日期、时间和时间刻度,因此可以在各种情况下使用它来管理日期。 日期格式 Python 3支持多种日期格式,如下所示: “Y…

不怕得罪人地推荐这9本黑客书籍

[利益声明] 1、这9本都和我有些关系或缘分,也是我至少过了一遍的,虽然并没都仔细推敲,但是这些书,我还是不得不点个赞。 2、其中一本是我和 xisigr 写的:-)我并不觉得在这不能推荐,因为这本书毕竟卖得很好。 然后&am…

torch.nn.functional.normalize参数说明

torch.nn.functional.normalize参数说明 函数定义参数及功能官方说明三维数据实例解释参数dim0参数dim1参数dim2参数dim-1 参考博文及感谢 函数定义 torch.nn.functional.normalize(input, p2.0, dim1, eps1e-12, outNone) # type: (Tensor, float, int, float, Optional[Tens…

chatgpt赋能Python-python3_9怎么安装jieba库

Python3.9怎么安装jieba库 随着大数据时代的到来,中文分词是一个愈发重要的问题。而jieba是一个基于Python的中文分词工具包,具有高速、易用、解耦的特点,广受开发者的青睐。本文将介绍如何在Python3.9环境下安装jieba库。 什么是jieba库 …

微服务: Seata AT 分布式事务以及配置方式(上篇)

目录 前言简介: 1. 安装seata-at -> 1.1 先看版本, 全局搜一下 -> 1.2 版本说明 alibaba/spring-cloud-alibaba Wiki -> 1.3 选择seata-at版本 -> 1.4 下载后按照下图进行创建文件 ---> 1.4.0 先在nacos创建命名空间seata ---> 1.4.1 registry.conf…

Chrome 的骑士盾,谷歌 Security Princess 访谈

童话故事里的公主都有一种需要被保护的感觉,就像马里奥大叔在这么多年来都要在库巴手上拯救出碧姬公主一样。不过在谷歌的这位 Security Princess 却手执盾牌,守护着大家的 Chrome 浏览器免受恶意程序攻击。小编这次就乘着世界网络安全日的机会&#xff…

微信小程序-生命周期

为什么今天突然总结一下微信小程序的生命周期呢?因为突然发现这个知识点忘得有点干净。所以今天就看一下微信小程序的生命周期是怎么个事吧! 目录 生命周期 生命周期的分类 生命周期函数的作用 生命周期函数的分类 生命周期是指一个对象从创建->…

Docker -- m1芯片 macOS 安装 nginx - 03

m1芯片 macOS 安装 nginx 一、安装docker提前准备二、下载nginx相关镜像三、运行相关容器四、运行并验证 一、安装docker提前准备 查看 d o c k e r \color{#FF7D00}{docker} docker版本:在 c o m m e n t \color{#FF7D00}{comment} comment 中输入 docker -version…

小红薯笔记/帖子采集工具

小红书【笔记/帖子】采集工具 链接: http://106.53.68.168:9920/xhs-keyword-spider 规则及操作 (1)规则: 按照关键词抓取规则:标题中或者正文内容中包含该关键词都能被抓取下来。多种搜索模式可选,分别…

字节跳动10年经验,10W字228道软件测试经典面试题总结(附答案)

前言 最近有很多粉丝问我,有什么方法能够快速提升自己,通过阿里、腾讯、字节跳动、京东等互联网大厂的面试,我觉得短时间提升自己最快的手段就是背面试题,最近总结了软件测试常用的面试题,分享给大家,希望…

【mpvue】小程序开发入门

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍mpvue的使用。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习知识,共同进步。 🥞喜欢的朋友可以关注一下,下次更…

Atlassian攻略:如何将Jira和Confluence的数据平稳迁移上云

迁移到云端相当于一次专业的冒险旅⾏。过程中肯定会经历一些颠簸,但只要有正确的心态和充分的准备,您就能完美应对。最终的目的地一定会让你感觉值得。当Atlassian调查了最近迁移的客户时,有89%的客户表示在他们不到6个月的时间内就意识到了迁…

chatgpt赋能Python-python3_9_7怎么换行

Python3.9.7是一款强大的编程语言,它具有许多优点,例如易于学习和使用,适用于不同的应用程序,以及具有丰富的第三方库支持。但是,许多人可能会面临一个问题:如何在Python3.9.7中正确换行? 在本…

一篇文章告诉你如何入门黑客技术

01 准备 当你决定做要开始学习一个新的领域时,你需要考虑以下几个问题。 1)要考虑清楚你为何要学这个 说白了就是你的动机是什么,如果你的动机是不可持续的,例如盗个QQ(甚至是挖个系统0Day漏洞)&#x…