简介

synchronized锁共有偏向锁、轻量级锁、重量级锁三种类型,而这三种类型的加锁方式都是相同的,写代码时不用考虑加哪种锁。使用锁时对象首先会变为偏向锁状态,当有其它线程获取锁时会升级为轻量级锁(没有竞争锁),若有线程竞争锁时,直接升级为重量级锁。

一、偏向锁

当创建对象时该对象的对象头状态会变成偏向锁状态(即使不加synchronized也是默认偏向锁状态,即Biased状态。thread指向偏向的线程,当有线程再次获取锁时,会判断是否为偏向的线程,如果是就可以直接执行同步代码块的内容。若不是,偏向锁升级为轻量级锁。

优点:加锁和释放锁的过程比较耗时,偏向锁不需要频繁的加锁和释放锁。

注意:1、当开启偏向锁时(默认开启),创建一个对象,对象的Mark Word为偏向锁状态,偏向锁是默认延迟的,不会在程序启动时立即生效(几秒后才生效)。
        2、当禁用偏向锁时,新创建的对象为普通状态,即使该对象被synchronized修饰,也不会变为偏向锁状态。
        3、如果对象调用hashcode方法,会自动禁用偏向锁,是因为偏向锁的对象头中没办法存储hashcode,而轻量级锁和重量级锁的hashcode都存放在获得锁的线程中的栈帧中,当释放锁时会将hashcode、age等数据恢复给锁对象,对象头状态恢复为普通状态。

二、轻量级锁

1、概念

轻量级锁和偏向锁加锁方式一样,当偏向锁被其它线程获取时(未发生竞争),会自动升级为轻量级锁。

2、轻量级锁的加锁和释放锁的过程:

每个线程的栈帧都会包含一个锁记录,内部可以存储锁对象的Mark Word,如下图:

当Thread-0获取锁时,会将锁记录中的Object reference指向锁对象,并尝试用cas修改锁对象中的Mark Word,并将Mark Word的值存放在锁记录中,如果修改成功,如下:

这样的话锁对象的最后两位就是 00 表示加了轻量级锁。上述是cas操作成功的情况,什么情况下cas操作会失败呢?

情况一:其它线程已经持有了该对象的锁,表名此时发生了锁的竞争,轻量级锁会膨胀为重量级锁。

情况二:自己执行了synchronized的锁重入,那么再添加一条Lock Record作为重入的记数,如下图:

当退出synchronized代码块(解锁)时,如果有取值为null的锁记录时,表示有重入,这时重置锁记录,表示重入次数减1。当锁记录不为null时,会使用cas将Mark Word值恢复给对象。

注意:轻量级解锁过程中,cas将Mark Word的值恢复给锁对象时,如果此时锁已经膨胀为重量级锁,恢复会失败,即解锁失败,此时会走解重量级锁的流程,参照下文。

三、重量级锁

概念:

当线程竞争锁时会将锁膨胀为重量级锁。

重量级锁加锁过程:

假如线程0获得了轻量级锁,未释放锁时线程1尝试获取锁,此时轻量级锁膨胀为重量级锁,如下图:

线程1加锁时发现,该对象的锁已经被别的线程持有,且锁状态为轻量级锁(后两位为00)这时线程1会为锁对象申请Monitor锁,让锁对象的Mark Word指向Monitor的地址,线程1进入Monitor的Entrylist中,进入阻塞状态,如下图:

重量级锁释放锁过程:

当线程0进入释放锁时,使用cas将Mark Worked的值恢复给锁对象时,失败,会进入重量级锁的解锁过程,即按照Monitor地址,设置Owner为null,并唤醒阻塞队列中的线程。

注意:在重量级锁中,Object原来的Mark Word值会存放在Monitor中,当解锁时,Monitor会将Mark Word的值恢复给锁对象。

Java synchronized偏向锁、轻量级锁、重量级锁相关推荐

  1. Java Synchronized 偏向锁/轻量级锁/重量级锁的演变过程

    前言 线程并发系列文章: Java 线程基础 Java 线程状态 Java "优雅"地中断线程-实践篇 Java "优雅"地中断线程-原理篇 真正理解Java ...

  2. synchronized锁升级之重量级锁

    目录 一.什么是重量级锁? 二.重量级锁的演示 三.重量级锁的原理 四.锁的优缺点对比 一.什么是重量级锁? 当有大量的线程都在竞争同一把锁的时候,这个时候加的锁,就是重量级锁. 这个重量级锁其实指的 ...

  3. Java synchronized偏向锁后hashcode存在哪里?

    今天的文章从下面这张图片开始,这张图片Java开发们应该很熟悉了 我们都知道无锁状态是对象头是有位置存储hashcode的,而变为偏向锁状态是没有位置存储hashcode的,今天我们来通过实现验证这个 ...

  4. java多线程之锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁

    转载至:https://blog.csdn.net/zqz_zqz/article/details/70233767 之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比 ...

  5. 【Java 并发编程】线程锁机制 ( 锁的四种状态 | 无锁状态 | 偏向锁 | 轻量级锁 | 重量级锁 | 锁竞争 | 锁升级 )

    文章目录 一.悲观锁示例 ( ReentrantLock ) 二.重量级锁弊端 三.锁的四种状态 ( 无锁状态 | 偏向锁 | 轻量级锁 | 重量级锁 ) 四.锁的四种状态之间的转换 ( 无锁状态 - ...

  6. Java如何避免重量级锁,Java 中锁是如何一步步膨胀的(偏向锁、轻量级锁、重量级锁)...

    文章目录 重量级锁(Mutex Lock) 偏向锁(比较 ThreadID) 偏向锁获取过程 偏向锁的释放 轻量级锁(自旋) 轻量级锁的加锁过程 轻量级锁的释放 总结 重量级锁(Mutex Lock) ...

  7. 轻量级锁_Java高级架构师-Java锁的升级策略 偏向锁 轻量级锁 重量级锁

    欢迎关注头条号:Java小野猫 这三种锁是指锁的状态,并且是专门针对Synchronized关键字.JDK 1.6 为了减少"重量级锁"的性能消耗,引入了"偏向锁&quo ...

  8. java轻量级和重量级_Java 偏向锁、轻量级锁和重量级锁

    前言 最开始听到偏向锁.轻量级锁和重量级锁的概念的时候,我还以为是 Java 中提供了相应的类库来实现的,结果了解后才发现, 这三个原来是虚拟机底层对 synchronized 代码块的不同加锁方式. ...

  9. Java锁---偏向锁、轻量级锁、自旋锁、重量级锁

    Java锁-偏向锁.轻量级锁.自旋锁.重量级锁 之前做过一个测试,反复执行过多次,发现结果是一样的: 单线程下synchronized效率最高(当时感觉它的效率应该是最差才对): AtomicInte ...

最新文章

  1. python创建django项目语句_简单了解Django项目应用创建过程
  2. 《Java 核心技术卷1 第10版》学习笔记------调试技巧
  3. python中复制、浅层拷贝、深层拷贝的区别
  4. 真实AIS数据,解码,可视化
  5. mui ajax 文件上传,MUI的图片上传和压缩
  6. 剖析VC中的文件操作
  7. oracle资产负债表重分类吗,【好会计】讲讲资产负债表中的重分类!
  8. 学java里面包括php_【学习java和PHP区别你知道多少】
  9. STM32 RCC时钟配置
  10. CCF201809-3 元素选择器(100分)【文本处理】
  11. Linux卸载jdk
  12. matlab迭代实验总结,0618法matlab实验报告
  13. 谁蹭了我的WiFi?浅谈家用无线路由器攻防
  14. Java程序员不得不会的124道面试题(含答案)
  15. 浅谈程序员常去的社区
  16. 2008 SCI 影响因子(Impact Factor)
  17. VS2008 Pocket PC 2003 SE仿真程序上网设置
  18. 2. C语言 -- 打印
  19. Ubuntu 18.04及Snap体验——让Linux入门更简单(转))
  20. 在Win32下使用OpenGL

热门文章

  1. Response Header里的Server,X-Powered-By,X-AspNet-Version字段等敏感信息删除
  2. 微信电脑版如何修改聊天记录等文件存放位置 电脑版微信在哪里修改存储地址
  3. 趣小面,陆正耀的另一副底牌
  4. 【Wikipedia爬虫工具包的使用】请求超时、代理错误、SSLError
  5. C语言学习纯纯小白-1,C语言代码开头为什么要有#include <stdio.h>
  6. w7家庭版计算机策略,gpedit.msc win7家庭版
  7. 多元线性回归系数求解
  8. TPM零知识学习十一 —— tpm全安装流程复盘(下)
  9. TEST1笔记 200408
  10. Python_RuntimeError问题的解决