Synchronized锁的状态_如何判断synchronized 锁是否被占-程序员宅基地

技术标签: JAVA  

转自:https://blog.csdn.net/u010723709/article/details/50341631

1 对象头与锁

要了解Synchronized的锁,必须知道对象头是怎么回事。因此这个锁就保存在对象头中。Hotpot虚拟机的对象头分两部分信息,第一部分用于存储对象自身的运行时数据,如HashCode,GC分代年龄等,这部分数据长度在32位和64位虚拟机中分别为32bit和64bit,它又称为“MarkWord”,它是实现锁的关键。另一部分就是用于存储指向方法区对象类型数据的指针,如果是数组的话,还有一个额外的空间储存数组长度。
对象头是与对象自己数据无关的额外储存成本,因此考虑到空间效率,MarkWord会根据自身的状态进行复用,也就是说在不同的状态下,它的储存结构不一样。它的变化状态如下所示

在32位的HotSpot虚拟机中对象未锁定的状态下,Mark Word的32bit空间中的25bit用于储存对象的哈希码,4bit用于储存对象分代年龄,2bit用于储存锁标志位,1bit固定为0。

2 自旋锁与自适应自旋

通常我们称Sychronized锁是一种重量级锁,是因为在互斥状态下,没有得到锁的线程会被挂起阻塞,而挂起线程和恢复线程的操作都需要转入内核态中完成。同时,虚拟机开发团队也注意到,许多应用上的数据锁只会持续很多的一段时间,如果为了这段时间去挂起和恢复线程是不值得的,所以引入了自旋锁。所谓的自旋,就是让没有获得锁的线程自己运行一段时间的自循环,这就是自旋锁。自旋锁在JDK6以后已经默认开启,可以通过-XX:+UseSpinning参数来开启。
但这显然并不是最好的一种方法,不挂起线程的代价就是该线程会一直占用处理器。如果锁被占用的时间很短,自旋等待的效果就会很好,反之,自旋会消耗大量处理器资源。因此,自旋的等待时间必须有一定的限度,如果超过限度还没有获得锁,就要挂起线程,这个限度默认是10次,可以使用-XX:PreBlockSpin改变。
在JDK6以后又引入了自适应自旋锁,也就说自旋的时间限度不是一个固定值了,而是由上一次同一个锁的自旋时间及锁的拥有者状态来决定。虚拟机认为,如果同一个锁对象自旋刚刚成功获得锁,那么下一次很可能获得锁,所以允许这次自旋锁自旋很长时间、而如果某个锁很少获得锁,那么以后在获取锁的过程中可能忽略到自旋过程。

3 锁的升级过程

在Java 6中为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”,在Java中,锁共有4种状态,级别从低到高依次为:无状态锁,偏向锁,轻量级锁和重量级锁状态,这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级。

4 偏向锁

偏向锁实际上是一种锁优化的,其目的是为了减少数据在无竞争情况下的性能消耗。其核心思想就是锁会偏向第一个获取它的线程,在接下来的执行过程中该锁没有其他的线程获取,则持有偏向锁的线程永远不需要再进行同步。

4.1 偏向锁的获取

当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里储存锁偏向的线程ID。以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需要检查当前Mark Word中储存的线程是否指向当前线程,如果成功,表示已经获得对象锁;如果检测失败,则需要再测试一下Mark Word中偏向锁的标志是否已经被置为1(表示当前锁是偏向锁):如果没有则使用CAS操作竞争锁,如果设置了,则尝试使用CAS将对象头的偏向锁指向当前线程。


4.2 偏向锁的撤销

偏向锁使用一种等待竞争出现才释放锁的机制,所以当有其他线程尝试获得锁时,才会释放锁。偏向锁的撤销,需要等到安全点。它首先会暂停拥有偏向锁的线程,然后检查持有偏向锁的线程是否活着,如果不处于活动状态,则将对象头设置为无锁状态;如果依然活动,拥有偏向锁的栈会被执行,遍历偏向对象的锁记录,栈中的锁记录和对象头的Mark Word要么重新偏向其他线程,要么恢复到无锁或者标记对象不合适作为偏向锁(膨胀为轻量级锁),最后唤醒暂停的线程。

4.3 关闭偏向锁

偏向锁在Java运行环境中默认开启,但是不会随着程序启动立即生效,而是在启动几秒种后才激活,可以使用参数关闭延迟:
-XX:BiasedLockingStartupDelay=0 
同样可以关闭偏向锁
 -XX:UseBiasedLocking=false,那么程序默认进入轻量级锁。


5 轻量级锁

轻量级锁是JDK1.6之中加入的新型锁机制,它并不是来代替重量级锁的,他的本意是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。

5.1 轻量级锁加锁
线程在执行同步块之前,JVM会现在当前线程的栈帧中创建用于储存锁记录的空间(LockRecord),并将对象头的Mark Word信息复制到锁记录中。然后线程尝试使用CAS将对象头的MarkWord替换为指向锁记录的指针。如果成功,当前线程获得锁,并且对象的锁标志位转变为“00”,如果失败,表示其他线程竞争锁,当前线程便会尝试自旋获取锁。如果有两条以上的线程竞争同一个锁,那么轻量级锁就不再有效,要膨胀为重量级锁,锁标志的状态变为“10”,MarkWord中储存的就是指向重量级锁(互斥量)的指针,后面等待的线程也要进入阻塞状态。


5.2 轻量级锁解锁
轻量级锁解锁时,同样通过CAS操作将对象头换回来。如果成功,则表示没有竞争发生。如果失败,说明有其他线程尝试过获取该锁,锁同样会膨胀为重量级锁。在释放锁的同时,唤醒被挂起的线程。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41904022/article/details/80681081

智能推荐

探秘Linux下正确获取物理内存大小的方法与技巧_linux 内存大小-程序员宅基地

文章浏览阅读1.3k次。在Linux系统中,正确获取物理内存大小是一个非常重要的任务。物理内存大小是计算机系统性能和资源管理的关键指标之一,它直接影响到系统的稳定性和性能。在本教程中,我们将介绍几种方法和技巧,帮助你在Linux系统中准确获取物理内存大小。_linux 内存大小

Mybatis 返回Map数据-程序员宅基地

文章浏览阅读3.5w次,点赞13次,收藏50次。Mybatis 返回Map数据_mybatis 返回map

JAVA获取邮件并保存为.msg_用java邮件API读取.msg文件..pls建议我-程序员宅基地

文章浏览阅读1.3k次。Simple Java Mail,通过SMTP发送电子邮件的开源库有一个EmailConverter类,它可以直接读取并将Outlook邮件转换为MimeMessage,Email或EML。// from Outlook .msgEmail email = EmailConverter.outlookMsgToEmail(readToString("yourMessage.msg"));Em..._java预览读取msg文件

耗时三小时整理的机器视觉知识-建议收藏转发_机器视觉3d定位耗时怎么划分-程序员宅基地

文章浏览阅读721次,点赞2次,收藏8次。2019-11-21 15:13:01随着工业4.0时代的到来,机器视觉在智能制造业领域的作用越来越重要,为了能让更多用户获取机器视觉的相关基础知识,包括机器视觉技术是如何工作的、它为什么是实现流程自动化和质量改进的正确选择等。小编为你准备了这篇机器视觉入门学习资料。机器视觉是一门学科技术,广泛应用于生产制造检测等工业领域,用来保证产品质量,控制生产流程,感知环境等。机器视觉系统是将被摄取..._机器视觉3d定位耗时怎么划分

利用matlab将位图转为SVG矢量图_位图转svg-程序员宅基地

文章浏览阅读5.3k次,点赞18次,收藏39次。利用matlab将位图转为SVG矢量图0 前言1 算法思路_位图转svg

MD5加密、用户管理、备份、EXPLAIN-程序员宅基地

文章浏览阅读110次。MD5在实际使用时一定要设计好MD5的规则,否则一旦更改将无法获取原数据,用户使用的是未加密的原数据,在java端按设定的规则进行MD5加密,将加密后的数据和数据库保存的加密过的数据对比,这样就能得知用户数据是否正确。看是否使用了索引,是否扫描了过多的行数,是否出现 Using temporary、Using filesort 等一些影响性能的主要指标。,网上的一些所谓MD5的破解只不过是将一些常见的整理成一个字典,然后去循环对比,如果MD5制定的规则稍复杂就会破解失败。key:实际使用的索引。

随便推点

C语言随机数生成_c ff随机数-程序员宅基地

文章浏览阅读1k次。#include <stdio.h>#include <time.h>#include <windows.h>int main(){ srand(time(NULL)); //随机数生成种子 int tmp = 0; for (int i = 0; i < 10; i++) { tmp = rand()%100+1; //生成1-100的随机整数 printf("%d\n", tmp); } return 0;}在实际使用时不要_c ff随机数

图像特征点提取及匹配的几种方法总结——基于C++和OPENCV实现SIFT、SURF、ORB、FAST_提取图像特征最新方法-程序员宅基地

文章浏览阅读4.1k次,点赞8次,收藏62次。学习特征提取匹配以及图像融合_提取图像特征最新方法

关于ccs5.5设置编码格式及VS code格式_vscode ccs-程序员宅基地

文章浏览阅读520次。1、在ccs中的代码导出到其他的地方的时候出现乱码的时候解决办法。然后导出的工程在对应的软件里面设置编码格式。2、修改vscode格式方法。选择通过编码重新打开。_vscode ccs

浅析Codewarrior、IAR和Keil MDK三大开发环境优缺点_iar greenhills-程序员宅基地

文章浏览阅读4.8k次,点赞4次,收藏13次。来源:没看到来源,抱歉。。向无名大神致敬啊。。今天打算拿出来几个IDE对比一下它们的优点和缺点,好给刚入门的初手一些参考。为 了避免存在误人子弟之嫌,我不会以我个人偏好下定义哪款好用哪款不好用,这里仅仅晒出自己一家之言,选择权还是在大家手里,毕竟好用不好用,用了才知道 (不要看广告看疗效,咳咳),适合自己的才是最好的。以M4为例(咳咳,自己成M4专业户了),目前基于M4的开发环境主要有Codewarrior10.1及以上、IAR6.1及以上、Keil MDK、CodeSourcery..._iar greenhills

软件售后服务与培训安装调试培训服务-程序员宅基地

文章浏览阅读359次,点赞4次,收藏7次。参加培训人员为系统管理人员、系统操作人员,主要培训内容包括:服务器端软件的配置过程、数据库管理方法、系统的安装、使用、维护,以及常见的技术问题的解决办法,软件培训不少于1天。为解决客户在系统使用中遇到的问题,保证该系统的正常运转,并以实际需要向客户提供及时有效的服务。承诺以健全的售后服务体系、多样的服务方式及丰富的服务内容,对甲方提供满意的售后服务服务和技术支持。远程服务:如果用户在我们技术人员指导下通过自己的操作仍然未能解决问题的,在客户授权的条件下,我们还可以为客户提供远程服务。

Oracle11g透明网关安装及配置附下载_oracle透明网关安装包-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏9次。Oracle11g透明网关安装及配置附下载(一) 安装oracle11g数据库安装路径可以随意,没有特殊规定,以后的oracle数据库配置文件要和此路径一致。(二) 安装Oralce的链接sql server的透明网关安装过程中需要注意的点为:要选择这个为sql server设计的网关;选执行典型配置:网关安装的路径为:安装路径没有特殊规定,与oracle共同目录下即可,为了方便以后维护。注:不要安装进oracle目录里,否则引发异常!!!(三) 相关文件的配置网关路径下的文_oracle透明网关安装包