Synchronized 底层原理总结

Synchronized的底层实现原理(看这篇就够了) 谈到多线程就不得不谈到Synchronized,重要性不言而喻,今天主要分享Synchronized的底层实现。 标题Synchronized synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是同步,也称之为”同步锁“。 synchronized的作用是保证在同一时刻, 被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果。 标题Synchronized的使用方式 主要有3种使用方式: 1.修饰实例方法:作用于当前实例加锁 pu. 阅读详情

一.synchronized介绍

synchronized是JVM内置锁,通过内部对象Monitor(监视器锁)来实现,基于进入与退出monitor对象来实现方法与代码块的同步,监视器锁的实现,最终依赖操作系统的Mutex lock(互斥锁)来实现。

二.synchronized使用方式

synchronized 主要有3种使用方式。

1.同步类方法

public synchronized void method()
{
   // todo
}

锁的是当前类对象;

2.同步代码块

public class TestNotes {
    private static Object object;

    public String decStock() {
        synchronized (object) {
            //todo
        }
        return "下单成功";
    }
}

或者

public  void run() {
   synchronized(this) {
      //todo
   }
}

锁的是括号里面的对象;

3.修饰一个类

lass ClassName {
   public void method() {
      synchronized(ClassName.class) {
         // todo
      }
   }
}

三.java对象组成

java对象由3部分组成:

  • 对象头 :比较复杂,synchronized加的锁,就保存在这里面的某些数据位。对象头大小是固定的;
  • 实例数据 :就是对象的业务数据;
  • 对齐填充位 :64位jvm,默认需要对象大小必须位8byte(字节)的整数倍,所以有时候需要对齐填充位。

Mark Word

其中,锁的不同状态,就是存在对象头中的Mark Word区域中,

下图是32位系统的Mark Word的区域具体分布:

四.锁的升级过程

synchronized锁有如下4种状态:

  • 无锁,不锁住资源,多个线程只有一个能修改资源成功,其他线程会重试;
  • 偏向锁,同一个线程获取同步资源时,没有别人竞争时,去掉所有同步操作,相当于没锁;
  • 轻量级锁,多个线程抢夺同步资源时,没有获得锁的线程使用CAS自旋等待锁的释放;
  • 重量级锁,多个线程抢夺同步资源时,使用操作系统的互斥量进行同步,没有获得锁的线程阻塞等待唤醒;

锁的升级过程:无锁-》偏向锁-》轻量级锁-》重量级锁。注意,升级并不一定是一级级升的,有可能跨级别,比如由无锁状态,直接升级为轻量级锁。

下面,我们以这段代码为例,分析以下锁的具体升级过程:

public class TestNotes {
    private static Object object;
    //减库存
    public String decStock() {
        synchronized (object) {
            //todo
        }
        return "下单成功";
    }
}

这段代码中,synchronized锁的是object实例对象,锁的具体状态,就保存在object对象头部的markword区域。

1、 无锁状态:

步骤说明:
1.synchronized锁的object对象头部markword区域,最开始锁状态标志位,默认值就是001,也就是无锁状态。

2、 偏向锁状态:

某刻,线程1执行到同步代码块,虚拟机会使用CAS尝试修改状态标志位,修改为偏向锁状态,并且把线程1的线程ID记录到markword区域的23bit位,进入偏向锁状态,如下图:

进入偏向锁状态后,如果没有其他线程竞争,线程1后续再次访问同步代码块时,犹如没有锁一样,jvm不会再进行CAS加锁、解锁等步骤,直接运行同步块代码。直到线程1执行完毕后,jvm会释放偏向锁,将markword的标识位恢复初始状态。

3、 轻量级锁状态:

线程1在持有偏向锁期间,线程2来了,下图右侧部分是线程2执行过程:

线程2访问同步代码块,尝试获取锁;此时jvm会检查线程1的状态,因为线程1还持有锁,jvm不能撤销线程1的锁,此时,jvm就会把锁升级位轻量级锁,也就是这个23bit区域存了线程1的地址,指向线程1的线程栈中的某块区域;同时线程栈的这块内存也保存了指向markword的引用,相当于两块区域互换了内容。

上文中描述的过程,是由无锁,然后变为偏向锁,然后是轻量级锁;
但是有些场景,锁会直接由无锁升级为轻量级锁,比如下图过程:

上图中,某一时刻,同时有两个线程执行到同步代码块,但实际肯定只能有一个线程先进入,假如是线程1,那么此时就会直接进轻量级锁状态。

此时,线程2就会进行CAS自旋,寻找机会获取轻量级锁,如下图:

4、 重量级锁状态:

上图中,进入轻量级锁状态后,线程2还会继续自旋尝试获取锁;这个时候,synchronized并不会立即进入重量级锁状态,而是等到线程2 自旋达到一定次数后,jvm才膨胀为下图的重量级锁。这个自旋次数,jdk7及以后可以通过jvm参数设置。

线程1执行完同步代码块,jvm尝试释放锁,修改markword为初始的无锁状态,在释放锁的时候,发现已经是重量锁了,说明有其他线程竞争,并且其他线程肯定已经进入了阻塞状态,那么jvm在释放锁之后,还会唤醒其他进入阻塞状态的线程。

五.总结

synchronized在jdk 1.6版本进行了优化,性能有了巨大提升,基本上和java锁性能没有什么差异,所以在生产环境中,synchronized能满足的场景,尽量使用synchronized,简单方便。

优化的关键,是加入了轻量级锁,使用CAS,还有自适应机制,避免了向底层操作系统申请互斥量,避免了用户态和内核态的切换,也就是在一定程度上避免了线程上下文的切换,暂时不进入重量级锁的状态。

系列面试题

另外一直在做Java面试连载的系列专栏,这回大家终于可以白嫖了

2021年中高级最全Java面试题,肝了!

阿里2021最全新的java面试题总结

字节跳动今日头条前端面经(4轮技术面+hr面)

吃透Java IO:字节流、字符流、缓冲流—最详细总结!

每日一面:1. JDK 、 JRE 、JVM有什么区别和联系?

Java高级进阶,你必须要掌握这些数据结构

Java并发面试,幸亏有点道行,不然又被忽悠了

Java面向对象设计?一招教你学会OOPS编程

java动态代理机制--那些让你面试脱颖而出的技能

你真正了解Java虚拟机吗—高级开发必备《深入了解Java虚拟机》

彻底理解Java中的值传递和引用传递

Java上亿级别秒杀系统优化 ,实现真正的高性能高并发!

深入了解JAVA的线程中断方法经验之总结

深入了解Java之类加载和案例分析

深入了解Java之垃圾回收

java设计模式六大原则之场景应用分析

在Java中如何优雅地判空

这样写简历,offer不给你给谁?

作者:雨剑yyy 链接:https://blog.youkuaiyun.com/csdn_20150804/article/details/104762106 来源:csdn

synchronized关键字是并发编程不可或缺的部分,Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:

普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁 静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁 同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。

Synchronized是Java中解决并发问题的一种最常用最简单的方法 ,他可以确保线程互斥的访问同步代码

个人认为能真实理解其内部运作原理能对平时的开发带来很大意义上的帮助,希望这篇文章能帮助你!

本文由博客一文多发平台 OpenWrite 发布!

synchronized 实现原理 两种同步方式本质上没有区别,只是方法的同步是一种隐式的方式来实现,无需通过字节码来完成。两个指令的执行是JVM通过调用操作系统的互斥原语mutex来实现,被阻塞的线程会被挂起、等待重新调度,会导致“用户态和内核态”两个态之间来回切换,对性能有较大影响。synchronized关键字经过Javac编译之后,会在同步块的前后分别形成monitorenter和monitorexit这两个字节码指令。这两个字节码指令都需要一个reference类型的参数来指明要锁定和解锁的对象。...... 阅读详情

相关推荐

synchronized原理详解(通俗易懂超级好)

目标 【理解】synchronized底层原理 【掌握】synchronized 的用法 目录目标一、synchronized原理1.1 原子性1.2 可见性1.3 有序性1.4 可重入性二、synchronized 的用法三、synchronized 的底层原理3.1 对象头在JVM中存储的形式3.1.1 对象头3.1.2 对象实例数据3.1.3 对齐填充3.2 Monitor3.3 synchronized锁的优化3.3.1 synchronized锁的状态3.3.2 偏向锁3.3.3. 轻量级锁3.

拉格朗日的学习笔记 1万+

Synchronized的底层实现原理(原理解析,面试必备)

synchronize的底层实现原理和monitor的实现机制

weixin_42460087的博客 3万+

在 Linux/Debian/Ubuntu 上使用 Brasero 刻录光盘

在 Ubuntu 系统中,Brasero 是一个非常方便的光盘刻录工具。无论是创建数据光盘、音频光盘还是刻录光盘镜像文件,Brasero 都能轻松胜任。本文将介绍如何在 Ubuntu 上安装和使用 Brasero 进行光盘刻录。

I AM COMING BACK... 3542

Java Synchronized原理

synchronized底层语义原理 Java 虚拟机中的同步(Synchronization)基于进入和退出管程(Monitor)对象实现, 无论是显式同步(有明确的 monitorenter 和 monitorexit 指令,即同步代码块)还是隐式同步都是如此。在 Java 语言中,同步用的最多的地方可能是被 synchronized 修饰的同步方法。同步方法 并不是由 monitorenter 和 monitorexit 指令来实现同步的,而是由方法调用指令读取运行时常量池中方法的 ACC_SYNC

lihuarui的专栏 743

Mac 不小心断开移动硬盘导致磁盘无法读取和加载(顺利解决!)

Mac移动硬盘不正确断开连接导致无法读取加载的解决方法,亲测有效

Robin_Pi的博客 1万+

利用随机矩阵理论(random matrix theory)确定微生物网络构建阈值

利用随机矩阵理论(random matrix theory)确定微生物网络构建阈值

微生物生态学分析 7637

一文彻底搞懂synchronized实现原理

synchronized 是 Java 中实现线程同步的关键字,用于保护共享资源的访问,确保在多线程环境中同一时间只有一个线程能够访问特定的代码段或方法。它提供了互斥性、可见性和有序性三个基本特性,确保了线程间操作的原子性和数据的一致性。

永远在路上 7509

数据中心GPU芯片性能参数速查表(Nvidia+国产算力卡)

本文提供了一份数据中心GPU芯片性能参数速查表,涵盖Nvidia与国产算力卡两大阵营。文章详细解读了算力、显存、互连技术及功耗等关键性能指标,并对比了A100、H100、昇腾910B等主流型号,旨在帮助用户根据AI训练、推理等实际场景,做出高效的硬件选型与成本评估决策。

a0b1c2d3的专栏 834

Synchronized底层核心原理

本篇文章是关于并发编程中Synchronized锁的底层核心原理知识记录,由于篇幅原因,下篇文章将介绍各种锁的优化原理。

小威的博客 8692

QGIS中高效处理CAD数据的两种实用技巧

本文详细解析了在QGIS中高效处理CAD数据的两种核心方法。针对DWG/DXF文件在QGIS中直接打开失败的问题,介绍了使用QGIS内置数据导入管理器进行标准化转换的流程,并重点推荐了功能更强大的Another DXF Importer插件,以更好地保留文字、块属性等复杂信息。文章对比了两种方法的优劣与适用场景,并提供了坐标系设置、中文乱码等常见问题的避坑指南,帮助用户根据数据需求选择最佳导入策略。

weixin_28363123的博客 116

从d、q轴电流到电机性能:FOC控制中角度偏移的实战影响与调试策略

本文深入探讨了永磁同步电机FOC控制中d、q轴电流与角度偏移对电机性能的影响及调试策略。通过分析角度偏移导致的效率下降、电流异常等问题,提供了实用的四步调试法和参数优化技巧,帮助工程师有效提升电机控制精度和效率。

weixin_29264201的博客 293

synchronized 底层实现原理?

synchronized 底层实现原理? 一、作用 确保线程互斥的访问同步代码 保证共享变量的修改能够及时可见 有效解决重排序问题 二、用法 修饰普通方法 修饰静态方法 修饰代码块 三、原理 同步代码块是通过 monitorenter 和monitorexit 指令获取线程的执行权 同步方法通过加ACC_SYNCHRONIZED 标识实现线程的执行权的控制 测...

ConstXiong 1万+

Windows Docker + RK3588 部署 YOLO26-Pose 人体姿态检测

YOLO26-Pose 在 RK3588 上的部署流程是 Windows Docker 容器内 ONNX 导出 → RKNN 转换(INT8 量化)→ ADB 推送 → 板端 C++ 推理。YOLO26n-Pose 在 640 输入下全链路约 55 FPS,可以覆盖实时姿态检测需求。先在板端用单张图片验证关键点输出正确性,确认 C++ 后处理的解析逻辑无误后,再切换到摄像头实时推理。

m0_64661770的博客 98

synchronized底层原理

synchronized底层原理 我们都知道synchronized可以让代码同步,所谓同步代码就是在同一时刻只能有一个线程执行这段代码。 synchronized可以锁对象,例如 pubilc class Demo{ private Object object; public Demo (Object obj){ this.obj = obj; } pubilc void method(){ synchronized(obj){

weixin_44900773的博客 420

DA14531之搭建开发环境

DA14531之搭建开发环境

hejinwu1314的博客 1777

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Synchronized底层原理深入解析

synchronized是Java中的一个关键字,用于保证多线程访问共享资源时的互斥性。它可以用在方法或代码块上,用于加锁某个对象或者类,避免多个线程同时访问临界区代码,造成数据不一致或线程安全问题。为了减少锁竞争带来的性能瓶颈,Java提供了一些优化技术和策略来减少锁的粒度、提升锁的效率,从而提高多线程程序的性能。常见的优化策略有减少锁的粒度锁粗化和锁消除。特性主要功能显式锁,提供更多控制,如尝试锁、定时锁、可中断锁等用于线程等待某些任务完成后继续执行互斥控制,确保对共享资源的访问线程协调。

一碗黄焖鸡三碗米饭的博客 1553

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

三面阿里,最后问了Synchronized底层原理

一谈到多线程安全问题,我们总会想到加锁可以解决线程安全的问题,JAVA提供的锁有两个,一个是synchronized关键字,另外一个就是lock类。在JDK1.6之前,synchronized是一个重量级锁,使用不方便,性能低下。在JDK1.6之后,synchronized进行了很大的优化,加入了偏置锁、轻量级锁、自旋锁等,大大提高了synchronized的性能。现在一起看看Synchroniz...

qq_36526036的博客 5003

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

synchronized 的底层原理

synchronized 的底层原理

激流丶的博客 7440

深入 synchronized 底层原理

synchronized 的使用 synchronized 关键字是 Java 中锁的一种实现,常用于解决并发问题。 在 Java 中每个对象都可以作为锁。 synchronized 共有三种用法。 修饰静态方法,锁是当前对象的 Class 对象。 修饰普通方法,锁是当前实例对象。 修饰代码块,锁是 synchronized 括号里的对象。 synchronized 原理 利用反编译的来查看加...

xj13829061922的博客 1070

Synchronized底层原理

是 Java 中用于实现线程同步的一个关键字,它通过加锁机制来保证多线程环境下共享资源的线程安全。虽然我们在应用中使用时只需关注其功能,但它的底层原理其实涉及到 JVM 的同步机制和操作系统层面的原子操作。理解的底层原理,有助于我们深入理解它的性能开销、优化方式及其内部工作机制。

m0_69529796的博客 821

通俗易懂synchronized的底层原理

每个对象都是一个监视器锁(monitor),当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。**指令执行时,monitor的进入数减1,如果减1后进入数为0,那线程退出monitor,不再是这个monitor的所有者。这是因为静态成员不属于任何一个实例对象,归整个类所有,不依赖于类的特定实例,被类的所有实例共享。

qq_44373419的博客 917

Java 的 synchronized 底层原理

如果该对象的锁计数器为 0 ,则尚未被其他线程持有,则当前线程可以成功获取锁,计数器+1,从而实现可重入性,并继续执行同步代码块。偏向锁: 当一个线程第一次获取锁时,JVM 会将该线程标记为“ 偏向 ”状态,后续若该线程再获取该锁,无需进行额外同步过程。释放锁时同理,可重入锁的,每一次退出方法,就会将status减1,直至status的值为0,最后释放该锁。重量级锁: 当 CAS 失败无法获取锁,锁会升级为重量级锁,线程会被挂起,直到锁被释放。如果锁已被其他线程持有,则当前线程将会被阻塞,直到锁被释放。

欢迎来到空说的博客 1308

彻底理解Synchronized底层实现原理

这篇文章会记录Synchronized的常用使用场景与Synchronized的底层实现原理。虽然我们平时经常会在多线程中使用Synchronized关键字,但可能对于这个我们很熟悉的关键字的底层到底是怎样实现的没有过多关注。作为开发者,既然使用到了,可以试着去一步一步揭开下它的底层面纱。 为什么要使用Synchronized? 首先我们来看下这段代码 public class Demo { private static int count=0; public /*synch.

疯一样的女子 4594

Synchronized底层实现原理

Synchronized底层实现原理

在路上 266
上一篇: Github重磅教程,从0到1,边学边实战!
84696zuoguwz
博客等级 码龄5年 12粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值