当前位置: 首页 > news >正文

Synchronized 概述


1. 初识

synchronized 是 Java 中的关键字,是一种 同步锁可重入锁悲观锁。它修饰的对象有以下几种:
具体表现为以下3种形式。
对于普通同步方法,锁是当前实例对象。
对于静态同步方法,锁是当前类的 Class 对象。
对于同步方法块,锁是 synchonized 括号里配置的对象。

虽然可以使用 synchronized 来定义方法,但 synchronized 并不属于方法定义的一部分,因此,synchronized
关键字不能被继承。 如果在父类中的某个方法使用了 synchronized 关键字,而在子类中覆盖了这个方法,在子类中的这
个方法默认情况下并不是同步的,而必须显式地在子类的这个方法中加上 synchronized
关键字才可以。当然,还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法本身不是同步的,但子类调用了父类的同步方法,因此,子类的方法也就相当于同步了。

如果一个代码块被 synchronized 修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待持有锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况

  1. 获取锁的线程执行完了该代码块,然后线程释放对锁的占有;
  2. 线程执行发生异常,此时 JVM 会让线程自动释放锁。

那么如果这个获取锁的线程由于要等待 IO 或者其他原因(比如调用 sleep
方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待,试想一下,这多么影响程序执行效率。
因此就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断),通过 Lock 就可以办到。


2. synchronized 的底层字节码

synchronized 三种用法及其原理

2.1 同步代码块

通过反编译可以看到, 其实现使用的是 monitorenter 和 monitorexit 指令。

2.2 普通同步方法

在这里插入图片描述

调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置。如果设置了,执行线程会将先持有 monitor 然后再执行方法,最后在方法完成(正常和异常情况都算完成)时释放 monitor。

2.3 类同步方法

在这里插入图片描述

ACC_STATIC 和 ACC_SYNCHRONIZED 访问标志区分该方法是否是静态同步方法。


3. synchronized 锁的是什么

synchronized 用的锁是存在 Java 对象头里的。

3.1 什么是管程

管程 (英语:Monitors,也称为监视器) 是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。
这些共享资源一般是硬件设备或一群变量。对共享变量能够进行的所有操作集中在一个模块中。(把信号量及其操作原语“封装”在一个对象内部)管程实现了在一个时间点,最多只有一个线程在执行管程的某个子程序。管程提供了一种机制,管程可以看做一个软件模块,它是将共享的变量和对于这些共享变量的操作封装起来,形成一个具有一定接口的功能模块,进程可以调用管程来实现进程级别的并发控制。

在这里插入图片描述

3.2 monitor ObjectMonitor

在 HotSpot 虚拟机中, monitor 采用 ObjectMonitor 实现
ObjectMonitor.java ->> ObjectMonitor.cpp ->> ObjectMonitor.hpp

在这里插入图片描述

Java 中的每个对象天生都带着一个对象的监视器(所以 Java 中任何一个对象都可以成为一个锁)。
任何对象都有一个 monitor 与之关联,当且一个 monitor 被持有后,它将处于锁定状态。线程执行到 被 synchronized 修饰的方法时,将会 尝试获取对象头的 monitor 的所有权,即尝试获得对象的锁。

http://www.dtcms.com/a/360513.html

相关文章:

  • 【LeetCode】18、四数之和
  • LeeCode 37. 解数独
  • 并发编程——10 CyclicBarrier的源码分析
  • Selenium 等待机制:编写稳定可靠的自动化脚本
  • spi总线
  • 7.2elementplus的表单布局与模式
  • MCP SDK 学习二
  • 艾体宝案例 | 数据驱动破局:DOMO 如何重塑宠物零售门店的生存法则
  • Python 2025:AI代理、Rust与异步编程的新时代
  • 张柏芝亮相林家谦演唱会 再次演绎《任何天气》
  • Spring MVC 九大组件源码深度剖析(五):HandlerAdapter - 处理器的执行引擎
  • 三、环境搭建之Docker安装mysql
  • 一、计算机系统知识
  • Springcloud-----Nacos
  • 【influxdb】InfluxDB 2.x 线性写入详解
  • 层次分析法
  • Redis实现短信登录
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘SQLModel’问题
  • 37. 解数独
  • 解锁Tensor Core性能:深入探索CUDA Warp矩阵操作
  • Dify构建AI应用
  • FART 主动调用组件深度解析:破解 ART 下函数抽取壳的终极武器
  • #Datawhale 组队学习#8月-工作流自动化n8n入门-3
  • 第七章 使用角色和Asible内容集合简化Playbook
  • 4.4 光照(4) - 高光反射
  • 硬件工程师成长之路:从入门到精通的技术旅程
  • [Plecs基础知识系列]建立自定义模块/子系统(Subsystem)
  • C++ 面试高频考点 力扣 69. x 的平方根 二分查找 题解 每日一题
  • Linux网络socket套接字(中)
  • 切片语法[::-1]及其可用的类型