Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >并发基础之Synchronized原理

并发基础之Synchronized原理

作者头像
崩天的勾玉
发布于 2021-12-20 09:33:22
发布于 2021-12-20 09:33:22
2950
举报
文章被收录于专栏:崩天的勾玉崩天的勾玉

上篇文章和大家聊了聊hashmap和concurrenthashmap的结构、用法、原理,从这篇文章开始次我们来聊聊并发编程吧!本次我将带大家了解一下synchronized的原理。

synchronized从1.6优化了之后并不是上来就很重,而是有了多个锁状态,分别是偏向锁、轻量级锁、重量级锁。

1)「重量级锁」

synchronized是依赖jvm实现同步的,他在同步代码块里和同步方法的原理有一些区别: 1、同步代码块:通过monitorenter和monitorexit指令实现的,每个对象都有一个监视器锁monitor,monitor被占用的时候就说明这个对象处于一个锁定状态,而monitorenter指令的作用就是去获取这个monitor的所有权,monitorexit指令就是去释放monitor。我来说一下他们的机制: monitorenter:每个monitor有个进入数,当它为0的时候表示没有线程在占用,当前线程就可以进入monitor,并将进入数设置为1;那如果当前线程已经拥有这个monitor,又重新进入的话,进入数就会+1,这就是锁的重入;如果monitor已经被其他线程占有,那么当前线程进入阻塞状态,等待monitor被释放,再去尝试获取。 monitorexit:首先必须要拥有这个monitor才能去执行monitorexit,执行后进入数-1,如果到0了就退出这个monitor,不再拥有。其他线程可以尝试去获取。 2、同步方法:方法常量池中会多一个ACC_SYNCHRONIZED标识,调用方法的调用指令会让线程去获取monitor,获取成功的话再继续执行方法,方法执行完毕后再释放monitor,同一个monitor同一时刻只能被一个线程拥有。 「总结」:二者都需要获取和释放monitor来实现线程同步,monitor的实现依赖于操作系统的mutex互斥锁,操作系统的线程之间的切换需要从用户态切换到内核态,开销比较大。

「2)轻量级锁」

相对于使用mutex的重量级锁来说的,他的实现主要是基于对象头的mark Word,线程进入同步方法或者同步代码块的时候,如果同步对象处于无锁状态(锁标志位为"01"状态,是否为偏向锁为"0),那么虚拟机会在栈帧里建立一个lock record(锁记录),获取锁的时候会把对象头的mark Word给拷贝过来,然后通过CAS操作把mark Word 更新为指向lock record的指针,更新成功后就拥有了该对象的锁,并把锁标志位改为00(轻量级锁)。 更新失败会检查mark Word是否是指向当前线程的,是的话表示当前线程已经有了这个对象的锁,然后进入代码块里执行。否则的话就表示已经被其他线程抢占了,然后就进入一个自旋,再次尝试cas更新指针。如果自旋结束还是没获取锁,那就膨胀为重量级锁,锁标志位状态值变为"10",Mark Word中储存就是指向monitor对象的指针,当前线程以及后面等待锁的线程也要进入阻塞状态。 释放锁就是通过cas将lock record里拷贝的markWord给替换回去,替换成功进入无锁状态;失败说明有其他线程尝试获取该锁(此时锁已膨胀),那就要在释放锁的同时,唤醒被挂起的线程。

「3)偏向锁」

如果说轻量级锁是在无竞争的情况下使用CAS操作区消除同步使用的互斥量,那么偏向锁就是把整个同步都消除掉. 检查Mark Word是否为可偏向锁的状态,即是否偏向锁即为1即表示支持可偏向锁,否则为0表示不支持可偏向锁。如果是可偏向锁,则检查Mark Word储存的线程ID是否为当前线程ID,如果是则执行同步块。如果检查到Mark Word的ID不是本线程的ID,则通过CAS操作去修改线程ID修改成本线程的ID,如果修改成功则执行同步代码块,否则执行步骤4。当拥有该锁的线程到达安全点之后,挂起这个线程,升级为轻量级锁。 释放: 偏向锁的释放采用了一种只有竞争才会释放锁的机制,线程是不会主动去释放偏向锁,需要等待其他线程来竞争。然后等待全局安全点(在这个是时间点上没有字节码正在执行)。暂停拥有偏向锁的线程,检查持有偏向锁的线程是否活着,如果不处于活动状态,则将对象头设置为无锁状态,否则设置为被锁定状态。如果锁对象处于无锁状态,则恢复到无锁状态(01),以允许其他线程竞争,如果锁对象处于锁定状态,则挂起持有偏向锁的线程,并将对象头Mark Word的锁记录指针改成当前线程的锁记录,锁升级为轻量级锁状态(00)。

比较

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 崩天的勾玉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【死磕Java并发】—–深入分析synchronized的实现原理
记得刚刚开始学习Java的时候,一遇到多线程情况就是synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决多线程情况的百试不爽的良药。但是,随着我们学习的进行我们知道synchronized是一个重量级锁,相对于Lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它。 诚然,随着Javs SE 1.6对synchronized进行的各种优化后,synchronized并不会显得那么重了。下面跟随LZ一
芋道源码
2018/03/02
8150
【死磕Java并发】—–深入分析synchronized的实现原理
吃透synchronized实现原理
记得刚刚开始学习Java的时候,一遇到多线程情况就是synchronized。对于当时的我们来说,synchronized是如此的神奇且强大。我们赋予它一个名字“同步”,也成为我们解决多线程情况的良药,百试不爽。但是,随着学习的深入,我们知道synchronized是一个重量级锁,相对于Lock,它会显得那么笨重,以至于我们认为它不是那么的高效。随着Javs SE 1.6对synchronized进行各种优化后,synchronized不会显得那么重。
码哥字节
2021/07/27
4930
synchronized的实现原理
    1)普通同步方法,锁是当前实例;     2)静态同步方法,锁是当前类的Class实例,Class数据存在永久代中,是该类的一个全局锁;     3)对于同步代码块,锁是synchronized括号里配置的对象。
在周末
2019/09/11
3940
Java并发-synchronized
利用synchronized实现同步的基础:Java中的每个对象都可以作为锁。具体表现为以下形式:
lpe234
2021/03/02
4250
深入理解synchronized工作原理与锁的优化
导读:synchronized 是 java 中最常用的保证线程安全的方式,synchronized 的作用主要有三方面:
码农架构
2021/03/24
1.3K0
synchronized详解
在Java中,synchronized锁可能是我们最早接触的锁了,在 JDK1.5之前synchronized是一个重量级锁,相对于juc包中的Lock,synchronized显得比较笨重。
三分恶
2021/03/03
6320
Java基础之Synchronized原理
思维导图svg: https://note.youdao.com/ynoteshare1/index.html?id=eb05fdceddd07759b8b82c5b9094021a&type=no
Ryan-Miao
2020/07/01
4750
Java并发编程:synchronized和锁优化
1. 使用方法 synchronized 是 java 中最常用的保证线程安全的方式,synchronized 的作用主要有三方面: 确保线程互斥的访问代码块,同一时刻只有一个方法可以进入到临界区 保证共享变量的修改能及时可见 有效解决重排序问题 语义上来讲,synchronized主要有三种用法: 修饰普通方法,锁的是当前对象实例(this) 修饰静态方法,锁的是当前 Class 对象(静态方法是属于类,而不是对象) 修饰代码块,锁的是括号里的对象 2. 实现原理 2.1. 监视器锁 synchroniz
butterfly100
2018/04/16
8920
Java并发编程:synchronized和锁优化
java并发编程实战(2) 线程同步synchronized
synchronized保证语句块内操作是原子的,所谓原子性就是指一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。被synchronized修饰的类或对象的所有操作都是原子的,因为在执行操作之前必须先获得类或对象的锁,直到执行完才能释放,这中间的过程无法被中断。synchronized和volatile最大的区别就在于原子性,volatile不具备原子性。
黄规速
2022/04/14
4900
java并发编程实战(2) 线程同步synchronized
什么是Synchronized?
Java对象头是synchronized实现的关键,Synchronized用的锁是存在Java对象头中
Java技术债务
2022/08/09
2550
Synchronized深入分析
Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。
Anymarvel
2020/09/23
6950
synchronized 与多线程的哪些关系
JVM 实现的 synchronized JDK 实现的 ReentrantLock
BUG弄潮儿
2022/06/30
2800
synchronized 与多线程的哪些关系
并发编程学习笔记02-Java并发机制的底层原理之synchronized
synchronized实现同步的基础:Java中的每一个对象都可以作为锁。具体表现为三种形式:
WindCoder
2020/01/22
3300
超硬核Synchionized底层实现原理
synchronized实现同步的基础是:Java中的每个对象都可作为锁。所以synchronized锁的都对象,只不过不同形式下锁的对象不一样。
名字是乱打的
2021/12/22
3070
超硬核Synchionized底层实现原理
synchronized—深入总结
传统的锁(也就是下文要说的重量级锁)依赖于系统的同步函数,在linux上使用mutex互斥锁,这些同步函数都涉及到用户态和内核态的切换、进程的上下文切换,成本较高。对于加了synchronized关键字但运行时并没有多线程竞争,或两个线程接近于交替执行的情况,使用传统锁机制无疑效率是会比较低的。
用户5325874
2020/01/16
5980
synchronized—深入总结
Synchronized实现原理与常见面试题
Synchronized 是常被我们用来保证临界区以及临界资源安全的解决方案。它可以保证当有多个线程访问同一段代码,操作共享数据时,其他线程必须等待正在操作线程完成数据处理后再进行访问。即 Synchronized 可以达到线程互斥访问的目的。
烂猪皮
2023/09/03
6420
Synchronized实现原理与常见面试题
52.说一下 synchronized 底层实现原理?_synchronized底层实现
说起多线程同步,一般的方案就是加锁,而在 java 中,提到加锁就想起 juc 包提供的 Lock 接口实现类与默认的关键字 synchronized 。我们常听到,juc 下的锁大多基于 AQS,而 AQS 的锁机制基于 CAS,相比起 CAS 使用的自旋锁,Synchronized 是一种重量级的锁实现。
全栈程序员站长
2022/09/23
2.2K1
52.说一下 synchronized 底层实现原理?_synchronized底层实现
并发编程锁之synchronized(二)
并发编程中数据同步需要依赖锁进行控制,上篇博文通过ReentrantLock源码分析也对Lock实现锁机制的大致原理有了一个了解,Lock主要是通过编码的方式实现锁,其核心就是:CAS+循环,CAS原子操作需要依赖底层硬件层特殊的CPU指令。这节我们来看下Java中另一种非常常见的实现同步的方式:synchronized。synchronized主要通过底层JVM进行实现,而且JVM为了优化,产生偏向锁、轻量级锁、重量级锁,由于其处于JVM底层实现中,对很多并发编程人员来说能清晰理解它们间的区别还是件困难的事。通过本篇博文,构建出对Java中锁得体系结构,让你对其有个更系统全面的认知。
技术zhai
2019/02/15
4480
深入理解synchronized底层原理,一篇文章就够了!
如果某一个资源被多个线程共享,为了避免因为资源抢占导致资源数据错乱,我们需要对线程进行同步,那么synchronized就是实现线程同步的关键字,可以说在并发控制中是必不可少的部分,今天就来看一下synchronized的使用和底层原理。 一、synchronized的特性
挨踢小子部落阁
2019/07/16
8630
快速掌握并发编程---锁优化篇
重量级锁就是如果存在线程竞争,会把线程 挂起来,等其他线程释放锁后,再去唤醒挂起的线程。因为线程的挂起和唤醒需要从内核态到用户态的切换,这个切换需要操作系统的支持,性能消耗非常大。
田维常
2020/10/23
3120
快速掌握并发编程---锁优化篇
相关推荐
【死磕Java并发】—–深入分析synchronized的实现原理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档