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

Java并发编程:synchronized机制

1. 简介

  synchronizedJava 中最基本的一种同步机制,是 Monitor 机制(监视器机制或管程机制)在 JVM 中的实现,使用 synchronized 时关联的 Java 对象被称为监视器对象, 而被 synchronized 保护的代码被称为同步代码块(或者临界代码区),同一时刻只能有一个线程执行同步代码块,synchronized 有四个特性:

  1. 原子性:被 synchronized 保护的代码块的执行式原子的;
  2. 可见性:在同步代码块中被修改的共享变量会在锁释放之前刷新到主存当中,保证资源变量的可见性;
  3. 有序性:Java允许编译器和处理器对指令进行重排序,但是指令重排并不会影响单线程的顺序,它影响的是多线程并发执行的顺序性,但是被 synchronized 保护的同步代码块,在执行过程中实际上被串行化,同一时刻只允许有一个线程执行同步代码块,因此 synchronized 可以保证同步代码块的有序性;
  4. 可重入性:synchronized 使用的锁是可重入的,当一个线程试图操作一个由其他线程持有的对象锁的临界资源时,将会处于阻塞状态,但当一个线程再次请求自己持有对象锁的临界资源时,这种情况属于重入锁,通俗一点讲就是说一个线程拥有了锁仍然还可以重复申请锁。

2. Monitor 机制简介

Monitor 机制主要包含两种机制

  1. 互斥同步机制:由 Monitor 机制同步的临界区,线程之间只能进行互斥访问,每一时刻只有一个线程可以进入临界区;
  2. 等待唤醒机制:又叫条件机制,由于 Monitor 机制采取互斥同步机制,因此,为了防止线程等待其他资源而长时间占有锁,Monitor 机制还包含条件机制,线程可以在某条件未发生时,先挂起阻塞并释放锁给其他线程,等待条件发生时再被唤醒;

实现互斥同步机制需要互斥锁,实现条件机制需要条件对象来提供提供等待通知功能。

3. 监视器对象

  前文介绍了 synchronizedJVM 中的 Monitor 机制,而管程机制需要互斥锁和条件对象,在 JVM 中互斥锁和条件对象的角色都由 Java 对象来扮演,作为互斥锁和条件对象的 JAVA 对象被称为监视器对象,任何 Java 对象都可以作为监视器对象,监视器对象同时承担互斥锁和条件对象的角色,我们看看具体是如何实现的。

Java 对象头

JVM 中,Java 对象包含三个部分:对象头、实例数据、对齐填充,其中对象头一般由 8 个字节 64 个比特位组成,其中前 4 个字节 32 个比特位是标记域(Mark Word),Mark Word 里默认存储对象的 HashCode、分代年龄和锁标记位,其中最后两个比特位就是锁标记位,Mark Word 里面的内容会随着锁标记位的变化而变化。

监视器对象的锁策略

synchronized 管程机制中,监视器对象扮演了锁的角色,在 JDK1.6 之前,监视器的互斥锁只采用了重量级锁策略,而在 JDK1.6 之后,JVM对监视器锁进行了优化,采用混合锁策略并且实现了锁膨胀机制,我们先介绍各种锁策略。

  1. 重量级锁:使用底层操作提供的互斥量来实现锁,比如 linux 操作系统的 mutex,由于重量级锁需要使用底层操作系统提供的资源,因此需要进行系统调用,从而产生用户态到内核态的切换,而且竞争锁失败的线程会被操作系统挂起,等待锁释放;当对象头中的锁标记位为 0b10 时,对象头中 Mark Word 其他比特位的内容变成指向系统互斥量的指针。
  2. 轻量级锁:使用进程内的私有变量 + CAS操作来实现锁,比如锁标记位为 0b00 时,表示使用轻量级锁,轻量级锁通过基于 CAS 操作的同步算法来修改对象头的 Mark Word 域,修改成功,说明当前线程获取锁,如果修改失败,说明发生了竞争,于重量级锁不同,轻量级锁竞争失败后,需要调用方对竞争失败的线程进行同步处理,JVM 采取了自旋重试的策略。
  3. 偏向锁:偏向锁假定将来只有第一个申请锁的线程会使用锁,因此将第一个获取锁的的线程ID通过 CAS 记录在 Mark Word 中,如果记录成功,则偏向锁获取成功,将锁标记位改为 0b01 ,之后如果申请锁的线程ID等于偏向锁绑定的线程ID,就可以直接进入临界区。
锁膨胀机制

目前的JVM对监视器锁采取锁膨胀或锁升级机制,根据实际情况对锁策略进行膨胀升级,其升级方向是:无锁——>偏向锁——>轻量级锁——>重量级锁,锁策略升级之后是无法降级的。具体升级的过程如下:
1.

相关文章:

  • vue2 根据不同路由url设置不同的网页背景颜色
  • android display 笔记(十四)VAU 和GSP 分别代表什么
  • 谷歌量子计算机:开启计算新纪元
  • 鸿蒙OSUniApp 实现的表单验证与提交功能#三方框架 #Uniapp
  • 2021-10-25 C++三的倍数含五
  • 【图片识别工具】批量单据识别批量重命名,批量OCR识别图片文字并重命名,批量改名工具的使用步骤和注意事项
  • OpenCv高阶(4.0)——案例:海报的透视变换
  • 无需付费,安装就能使用!
  • 高效电脑隐私信息清理实用工具
  • 贪吃蛇游戏消息通知功能开发全解析
  • iptables 防火墙
  • Java中Money类的使用及与BigDecimal的对比
  • 软考软件评测师——计算机组成与体系结构
  • Sumsub 活体检测与人证对比 Java Demo
  • zabbix7.2 zabbix-agent自动注册 被动模式(五)
  • 层序遍历(BFS)核心逻辑:从二叉树到复杂题型的一通百通
  • 初识Linux · IP分片
  • 牛客网 NC22167: 多组数据a+b
  • ROS--NAVI DWA
  • 牛客网刷题:NC208813求逆序数
  • 竞彩湃|欧联杯决赛前,曼联、热刺继续划水?
  • 坚持吃素,是不是就不会得高血脂了?
  • 基金经理调仓引发大金融板块拉升?公募新规落地究竟利好哪些板块
  • 讲武谈兵|视距外的狙杀:从印巴空战谈谈超视距空战
  • 盛和资源海外找稀土矿提速:拟超7亿元收购匹克,加快推动坦桑尼亚项目
  • 3年多来俄乌要首次直接对话?能谈得拢吗?