前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java并发-synchronized

Java并发-synchronized

作者头像
lpe234
发布于 2021-03-02 07:33:50
发布于 2021-03-02 07:33:50
41400
代码可运行
举报
文章被收录于专栏:若是烟花若是烟花
运行总次数:0
代码可运行

synchronizedJava提供的一种内置锁,通常叫做重量级锁。在Java SE 1.6对其进行了各种优化。

1 基本使用及原理

利用synchronized实现同步的基础:Java中的每个对象都可以作为锁。具体表现为以下形式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// ①普通同步方法,锁的是当前实例对象。
public synchronized void instanceLock() {
  // code
}

// ②静态同步方法,锁的是当前的Class对象。
public static synchronized void classLock() {
  // code
}

// ③同步方法块,锁是synchronized括号内配置的对象
final Object lock = new Object();
public void blockLock() {
  synchronized (lock) {
    // code
  }
}

// ④等同于①,锁的是当前实例对象。
public void instanceLock2() {
  synchronized (this) {
    // code
  }
}

// ⑤等同于②,锁的是当前的Class对象。
public void classLock2() {
  synchronized (this.getClass()) {
    // code
  }
}

当一个线程试图访问同步块时,必须先获得锁,正常退出或抛出异常时须释放锁。

JVM基于进入和退出Monitor对象来实现方法同步和代码块的同步。代码块同步使用monitorenter和monitorexit指令实现的,方法的同步使用ACC_SYNCHRONIZED标识。

monitorenter是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处,JVM要保证每个monitorenter必须有对应的monitorexit与之配对。任何一个对象都有一个monitor与之关联,当monitor被持有后,它将处于锁定状态。线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor所有权,即尝试获取锁。

2 Java对象头

synchronized用的锁是存在Java对象头中的。若果对象是数组类型,则虚拟机使用3个字宽(Word)存储对象头,如果对象是非数组类型,则使用2字宽存储对象头。在32位虚拟机中,1字宽等于4字节,即32bit。

Java对象头长度

长度

内容

说明

32/64bit

Mark Word

存储对象的HashCode、分代年龄和锁标识位

32/64bit

Class Metadata Address

存储到对象类型数据的指针

32/64bit

Array length

数组长度(如果是数组)

Mark Word格式

锁状态

29bit / 61bit

1bit是否偏向锁

2bit锁标志位

无锁

0

01

偏向锁

线程ID

1

01

轻量级锁

指向栈中锁记录的指针

该位不用于标识偏向锁

00

重量级锁

指向互斥量(重量级锁)的指针

该位不用于标识偏向锁

10

GC标记

该位不用于标识偏向锁

11

3 锁升级降级

Java SE 1.6为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”,在Java 1.6中,锁一共有4种状态:无锁状态 > 偏向锁状态 > 轻量级锁状态 > 重量级锁状态。

无锁就是没有对资源进行锁定,任何线程都可以尝试修改它。

几种锁会随着竞争情况逐渐升级,锁的升级很容易,但是锁降级发送的条件会比较苛刻,锁降级发生在Stop The World期间,当JVM进入安全点时,会检查是否有闲置的锁,然后进行降级。

3.1 偏向锁

HotSpot作者经研究发现,大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获取锁的代价更低而引入了偏向锁。

偏向锁会偏向于第一个访问锁的线程,如果在接下来的运行过程中,该锁没有被其他的线程访问,则持有偏向锁的线程将永远不需要触发同步。

3.1.1 实现原理

当一个线程第一次访问同步块并获得锁时,会在对象头和栈帧中的锁记录里存放偏向的线程ID。以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需要简单的测试下对象头的Mark Word里是否存储着指向当前线程的偏向锁。

若测试成功,则表示线程已经获得了锁;若测试失败,则表示有另外一个线程来竞争这个偏向锁。此时会尝试使用CAS来替换Mark Word里面的线程ID为新线程ID,这时有两种情况:

  • 成功,表示之前线程不存在了,Mark Word里面的线程ID为新线程ID,锁不会升级,仍为偏向锁。
  • 失败,表示之前的线程仍然存在,那么会暂停之前的线程,设置偏向锁标识为0,并设置锁标识位为00,升级为轻量级锁,会按照轻量级锁的方式进行竞争锁。
3.1. 偏向锁撤销及关闭

偏向锁使用了一种等到竞争出现才释放锁的机制,所以当其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁。

偏向锁升级成轻量级锁时,会暂停拥有偏向锁的线程,重置偏向锁标识。大概过程如下:

  • 在一个安全点(在这个时间点上没有字节码正在执行)停止拥有锁的线程。
  • 遍历线程栈,如果存在锁记录的话,需要修复锁记录和Mark Word,使其变成无锁状态。
  • 唤醒被停止的线程,将当前锁升级为轻量级锁。

如果程序里的锁常处于竞争状态,可以通过JVM参数关闭偏向锁:-XX:-UseBiasedLocking,那么程序默认会进入轻量级锁状态。

3.2 轻量级锁

多个线程在不同时段获取同一把锁,即不存在锁竞争的情况,也就没有线程阻塞。针对这种情况,JVM采用轻量级锁来避免线程的阻塞与唤醒。

3.2.1 轻量级锁加锁

线程在执行同步块之前,JVM会先在当前线程的栈桢中创建用于存储锁记录的空间,并将对象头中的Mard Word复制到锁记录中,官方称为Displaced Mark Word。然后线程尝试使用CAS将对象头中的Mark Word替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。

自旋是消耗CPU的,一直无法获取锁则一直处于自旋状态。JDK采用了适应性自旋,简单来说就是线程如果自旋成功则下次自旋次数增加,若失败则下次自旋次数会减少。

自旋并非一直自旋下去,如果自旋到一定程度(和JVM、OS相关),依旧没获取到锁,称自旋失败,那么线程会阻塞。同时锁将会升级成重量级锁。

3.2.2 轻量级锁解锁

轻量级解锁时,会使用原子的CAS操作将Displaced Mark Word内容复制回锁对象Mark Word里面。如果没有发生竞争,那么这个复制操作会成功。若有其他线程因为自旋多次导致轻量级锁升级成重量级锁,那么CAS操作会失败,此时会释放锁并唤醒被阻塞的线程。

3.3 重量级锁

重量级锁依赖于操作系统的互斥量(mutex)实现的,而操作系统中线程中间状态的转换需要相对比较长的时间,所以重量级锁效率比较低,但被阻塞的线程不会消耗CPU。

每个对象都可以当做一个锁,当多个线程同时请求某个锁对象时,对象锁会设置几种状态来区分请求的线程:

名称

描述

Contention List

所有请求锁的线程将被首先放置到该竞争队列

Entry List

Contention List中那些有资格成为候选人的线程被移到Entry List

Wait Set

那些调用wait方法被阻塞的线程将会被放到Wait Set

OnDeck

任何时刻最多只能有一个线程正在竞争锁,该线程成为OnDeck

Owner

获得锁的线程

!Owner

释放锁的线程

当一个线程尝试获取锁时,如果该锁已经被占用,则会将线程封装成一个ObjectWaiter对象插入到Contention List的队列的队首,然后调用park函数挂起当前线程。

如果线程获得锁后,调用Object.wait方法,则将线程加入到Wait Set中,当被Object.notify唤醒后,会将线程从Wait Set移动到Contention List或Entry List中去。需注意的是,当调用一个锁对象的wait或notify方法时,如果当前锁的状态是偏向锁或轻量级锁则会先膨胀成重量级锁。

4 锁的优缺点对比

优点

缺点

适用场景

偏向锁

加锁和解锁不需要额外的消耗,和执行非同步方法相比仅存在纳秒级的差距

如果线程间存在竞争,会带来额外的锁撤销的消耗

适用于只有一个线程访问同步块场景

轻量级所

竞争的线程不会阻塞,提高了程序的响应速度

如果始终得不到锁竞争的线程,使用自旋会消耗CPU

追求响应时间,同步块执行速度非常快

重量级锁

线程竞争不会适用自旋,不会消耗CPU

线程阻塞,响应时间缓慢

追求吞吐量,同步块的执行时间较长

5 总结锁升级流程

每个线程在准备获取共享资源时:

  • 第一步,检查MarkWord里面存放的是不是自己的ThreadId,若是则表示当前处于“偏向锁”。
  • 第二步,如果MarkWord不是自己的ThreadId,锁升级,这时候使用CAS来执行进行切换,新线程根据Mark Word里面现有的ThreadId,通知之前的线程暂停,之前的线程将MarkWord置空。
  • 第三步,两个线程都把锁对象的HashCode复制到自己新建的用于存储锁的记录空间,接着开始通过CAS操作,把锁对象的MarkWord的内容修改为自己新建的记录空间的地址的方式竞争MarkWord。
  • 第四步,第三步中成功执行CAS的获得资源,失败则进入自旋。
  • 第五步,自旋的线程在自旋的过程中,成功获得资源(即之前获得资源的线程执行完成并释放了共享资源),则整个状态依然处于轻量级锁状态,如果自旋失败。
  • 第六步,进入重量级锁状态,这个时候,自旋的线程进行阻塞,等待之前的线程执行完成并唤醒自己。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
邹良城:视频聚合类APP的网络版权侵权认定问题
  本文为作者在“第三届中国互联网新型版权研讨会——互联网+内容产业的生态发展及制度保障”上的发言。 邹良城  腾讯公司诉讼维权总监   各位领导,各位专家、同行,大家下午好,非常荣幸参加今天的
腾讯研究院
2018/03/06
2.9K0
邹良城:视频聚合类APP的网络版权侵权认定问题
像追女孩一样去渗透之信息收集
在IT行业摸索了很多年终于找到了一生所爱(信息安全),为了这份爱能传递下去,我将以这份脱单攻略来讲述我是如何get挚爱shell!希望大家都能get到女神的shell
黑伞安全
2019/10/16
3.2K0
《热血长安》网剧一举击破30亿播放量,影视娱乐今天得这样玩?
这几天又有一部网剧在微博火了,我关注的影视类大V都在转发《热血长安》的影评内容。“三口看片”发布的相关短视频在微博上转发量达到1.4万、在秒拍有600多万的播放;毒舌电影的一条短视频在秒拍播放有500
罗超频道
2018/04/26
7170
《热血长安》网剧一举击破30亿播放量,影视娱乐今天得这样玩?
PiliPala:开源项目真香,B站用户狂喜!这个开源APP竟能自定义主题+去广告?PiliPala隐藏功能大揭秘
嗨,大家好,我是小华同学,关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法
小华同学ai
2025/02/09
3500
PiliPala:开源项目真香,B站用户狂喜!这个开源APP竟能自定义主题+去广告?PiliPala隐藏功能大揭秘
【数据】常用API接口汇总
下面列举了100多个国内常用API接口,并按照 笔记、出行、词典、电商、地图、电影、即时通讯、开发者网站、快递查询、旅游、社交、视频、天气、团队协作、图片与图像处理、外卖、消息推送、音乐、云、语义识别、语音识别、杂志、综合 进行了如下分类。 笔记 OneNote - OneNote支持获取,复制,创建,更新,导入与导出笔记,支持为笔记添加多媒体内容,管理权限等。提供SDK和Demo。 为知笔记 - 为知笔记Windows客户端开放了大量的API,其中绝大部分,都通过COM提供,可以在javascript,
陆勤_数据人网
2018/04/18
20K1
“喂,你要不要让自己试试看?”
大家下午好,我是编辑小堂妹,今天深圳天气蛮不错的,想和大家唠唠嗑。 好啦,步入正题,不知道大家有没有和我一样,热衷于借鉴成功人士的经验。 每次看到小马哥、马爸爸、强东哥的发家史,总觉得其中总有一些方法
腾讯大讲堂
2018/07/12
4070
我膨胀了,测试必要商城小程序,用了3种方式!:)
搜一搜:如果从来没有搜索过,在这里点击一下它,历史记录是空的。但是如果曾经搜索过,那一定有历史记录。如果不是第一次点击它,用自动化脚本再次点击的话,不会让你输入进去,会报错。
清菡
2020/12/16
5370
我膨胀了,测试必要商城小程序,用了3种方式!:)
腾讯能否拿下搜狐视频,要看张朝阳能否忍痛割爱
近日,新浪科技报道称,搜狐内部人士透露腾讯将以认购的方式向搜狐视频注资10亿美金,这一消息或于不久后宣布。这一交易与当年腾讯入股搜狗颇为相似:即腾讯将通过现金投资+业务注入的方式进行投资,具体来说,腾讯视频将于搜狐视频整合为新的“搜狐视频”,搜狐视频将以搜狐子公司独立运营。2013年-2014年,腾讯开展了一系列甩包袱的举措:2013年将搜搜搜索和输入法业务并入搜狗并入股后者;2014年将拍拍和易迅并入京东并入股后者。 不过,腾讯入股搜狐视频这一传言还是让人有几分疑惑。 腾讯视频不是包袱,为何要甩掉? 腾
罗超频道
2018/04/27
9650
全局资源编排下载系统,所有资源通通拿下!用NAS打造完美的追剧娱乐中心 - 熊猫不是猫QAQ
我相信大家手里NAS大部分都会用来搭建影视系统,不管你是用emby、jellyfin还是付费plex,这些系统都需要本地资源的支持,而本地资源哪儿来呢?部分人手机拥有很多PT站点,那么对于他们来说,资源很好找而且很及时。有新出的片子都能第一时间获取到。而对于没有PT站的人来说,只能去免费的站点了,但是都有NAS了,自然需要一套全自动服务了。于是乎Kubespider便诞生了。
熊猫不是猫
2023/07/20
1.3K0
全局资源编排下载系统,所有资源通通拿下!用NAS打造完美的追剧娱乐中心 - 熊猫不是猫QAQ
使用Huginn打造自动化云端信息助手
半年前我在简书上分享过一篇文章——Huginn 安装教程—建立你自己的 IFTTT,简单地介绍了一下Huginn到底是什么以及它部署到Heroku云平台上的方法。后来,我和利器群里结识的几个群友一起完成了Huginn教程的翻译;就在上个月,我们把这些教程都放到了网上(托管Github和Coding),于是就有了现在的Huginn中文网。但是,当我向其他人推荐这个开源应用时,大家还是不理解这个应用到底有大的用途,或者是有哪些有趣的玩法,恐怕就连Huginn这个单词很多人都不知道它的意思,更不要说它其中的典故。所以,我想结合我这近十个月左右的使用经验跟大家谈一谈它。
huginn 中文网
2019/03/20
2K0
百度终于入局小程序,会是哪些行业的红利?
在腾讯、阿里、谷歌、Facebook等互联网巨头以及十大手机巨头相继推出类小程序的应用平台后,百度日前正式入局。5月22日,在百度联盟峰会分论坛上,百度App业务部总经理平晓黎表示,百度将于7月正式推出百度智能小程序。
罗超频道
2018/07/23
5780
百度终于入局小程序,会是哪些行业的红利?
不仅仅是代码链接:arXiv联手Papers with Code,推出两项新功能
据官方推特消息,Papers With Code联合arXiv推出了代码链接功能,以后在上传arXiv论文的时候,就能顺便提交代码,不需要在论文里默默地加上链接,然后被忽略啦!
AI科技评论
2020/10/27
1.3K0
不仅仅是代码链接:arXiv联手Papers with Code,推出两项新功能
弹幕挖掘在综艺节目热点分析中的应用初探
作者:黄耀鹏, 腾讯PCG数据分析工程师 |导语 视频弹幕作为视频内容延伸、以及用户喜好反馈的一部分,有着巨大的挖掘价值。本文旨在通过运用文本挖掘技术,从弹幕中挖掘综艺节目热点话题,助力平台精准把握用户消费偏好、提升节目运营效率。 声明:本文运营方案相关的思考为个人观点,不代表腾讯视频既有运营方案和平台价值取向。本文仅纯粹作为个人感兴趣的技术研究总结。抛砖引玉,期待感兴趣的同学一起交流探讨。 1. 业务场景思考 1.1 视频弹幕的本质 弹幕文化,首先兴起于ACG社区等小众群体。而随着B站等弹幕视频网站的
腾讯大讲堂
2020/12/02
1.7K0
Chrome 浏览器扩展神器油猴
我平常工作最常用的浏览器就是 Chrome 了,Google 出品,值得信赖,用 Chrome 就不得不提浏览器扩展了,有了各种 Chrome 扩展,可以让你浏览器网页更方便,工作更高效。
不安分的猿人
2020/03/02
2.6K0
HTML5崛起之时,Java桌面时代就已经终结了
2004 年 Google Maps 的面世标志着 Java 桌面时代的终结,也改变了桌面环境下“跨平台”的基本定义。
深度学习与Python
2022/04/19
8400
35张PPT,教你快速成为数据分析师
我入行互联网的契机是做了一个“网站分析”的微博账号,做自媒体跟真正的实践者还是有很大距离的,所以推荐一个list的,如果你对网站分析有兴趣,可以专注这些大牛!
IT阅读排行榜
2018/08/16
6030
35张PPT,教你快速成为数据分析师
荐读|2016年上半年中国互联网广告运营商市场大数据
2016年上半年中国互联网广告运营商市场规模达1187.1亿元人民币,同比增长27.3%。 竞争格局方面,百度、阿里巴巴、腾讯分别位居市场前三位置。相较于第1季度,第2季度百度占比有所上升,占26.9
灯塔大数据
2018/04/09
1.1K0
荐读|2016年上半年中国互联网广告运营商市场大数据
一文详解远程控制安全与远程控制软件(横测ToDesk\AnyDesk\向日葵)
远程控制的安全性已经算半个老生常谈的问题了,作为常年远程办公的人,这里我只想说一句,无论你用什么软件都会有安全上的隐患,做不到百分百的安全,但相对安全,咱们还是可以自主把控的。
海拥
2023/09/19
2K0
一文详解远程控制安全与远程控制软件(横测ToDesk\AnyDesk\向日葵)
【渗透技巧】资产探测与信息收集
另外,随着企业内部业务的不断壮大,各种业务平台和管理系统越来越多,很多单位往往存在着“隐形资产”,这些“隐形资产”通常被管理员所遗忘,长时间无人维护,导致存在较多的已知漏洞。
Bypass
2019/07/08
3K0
Docker搭建WordPress博客
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/101926.html原文链接:https://javaforall.cn
全栈程序员站长
2022/06/29
9380
Docker搭建WordPress博客
推荐阅读
相关推荐
邹良城:视频聚合类APP的网络版权侵权认定问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验