2019独角兽企业重金招聘Python工程师标准>>>

synchoronized在Jdk1.6之前一直被称为重量锁,性能较差,很少被推荐使用。synchoronized在Jdk1.6中进行了大量优化,性能与JUC中的各种锁无差,也被逐渐的被大众所接受。

synchoronized将锁状态记录在了对象头的MarkWord中,包含4种锁状态:无锁、偏向锁、轻量锁和重量锁,锁状态只能升级不能降级,即 无锁-->偏向锁-->轻量锁-->重量锁,目的是提高获取锁和释放锁的效率,对象几种状态的获取和释放如下:

  1. 偏向锁
          大多数情况下,锁不存在多线程竞争,而总是由同一线程获得,为了让线程获得锁的代价更低(消除了同步)而引入了偏向锁。当对象第一次被线程获取的时候,会把MarkWord中的偏向标识位设为01(偏向锁状态),同时使用CAS操作将该线程的ID记录在MarkWord中,如果CAS操作成功,则该线程每次进入到这个锁相关的同步块时,虚拟机都可以不进行任何同步操作。
          当有另外的线程获取这个锁时,偏向模式就结束了,根据锁对象目前是否处于锁定的状态,会恢复到无锁状态(01)或者变为轻量锁状态(00),借用《Java并发编程艺术》的一张图,如下所示:

  2. 轻量锁
          线程在执行同步块之前,JVM会先在当前线程栈帧中创建用于存储锁记录的空间,并将对象头中的MarkWord复制到锁记录中,官方称为Displaced Mark Word。然后线程尝试使用CAS操作将对象头中的MarkWord替换为指向锁记录的指针,如果成功,当前线程获得锁,如果失败,表示有其他线程竞争锁,当前线程开始自旋,如果自旋完成一定次数(可能是50次、100次,可以通过启动参数配置自旋次数)当前线程还没有获取到锁,那么锁会开始膨胀,进化为重量锁。
          轻量锁解决时,使用CAS操作将Displace Mark Word 替换会对象头,如果成功,则表示没有竞争,如果失败(已经有线程将锁的状态修改为重量锁),则释放锁并唤醒等待线程,借用《Java并发编程艺术》的一张图,如下所示:

  3. 重量锁
          由上面的轻量锁升级而来,一旦升级到重量锁,那么其他线程获取锁,都会被阻塞,等待释放锁。当持有锁的线程释放锁并唤醒等待线程时,等待的线程就会开始新一轮的竞争。

理解:

  • 当单个线程进入同步块,使用偏向锁,成本低,不需要使用CAS操作
  • 当两个线程依次进入同步块,使用轻量锁,单线程自旋也不会造成太多的CPU损耗
  • 当两个或多个线程进入同步快,使用重量锁,让获取锁的线程之外的线程进行阻塞等待唤醒,效率更高。

PS:使用openjdk的JOL(Java Object Layout)工具可以观察各种线程竞争锁时,Java对象头的状态。

参考书籍及网址:

  • 《Java并发编程艺术》

PS:研究基于MAC+Idea+JDK1.8 64位

Keep Calm and Carry on!

转载于:https://my.oschina.net/gordonfor/blog/2051786

Java并发编程基础-锁-synchronized状态变换相关推荐

  1. Java并发编程基础--ThreadLocal

    Java并发编程基础之ThreadLocal ​ ThreadLocal是一个线程变量,但本质上是一个以ThreadLocal对象为键.任意对象为值的存储结构,这个结构依附在线程上,线程可以根据一个T ...

  2. Java并发编程的艺术-Java并发编程基础

    第4章 Java并发编程基础 ​ Java从诞生开始就明智地选择了内置对多线程的支持,这使得Java语言相比同一时期的其他语言具有明显的优势.线程作为操作系统调度的最小单元,多个线程能够同时执行,这将 ...

  3. Java并发编程-无锁CAS与Unsafe类及其并发包Atomic

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772470 出自[zejian ...

  4. Java并发编程之锁机制之LockSupport工具

    关于文章涉及到的jdk源码,这里把最新的jdk源码分享给大家----->jdk源码 前言 在上篇文章<Java并发编程之锁机制之AQS(AbstractQueuedSynchronizer ...

  5. java 并发编程多线程_多线程(一)java并发编程基础知识

    线程的应用 如何应用多线程 在 Java 中,有多种方式来实现多线程.继承 Thread 类.实现 Runnable 接口.使用 ExecutorService.Callable.Future 实现带 ...

  6. Java并发编程 基础知识学习总结

    Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容,这部分的内容我也是反复学习了好几遍才能理解.本篇博客梳理一下最近从<Java 并发编程的艺术>和他人的博客学习Java并发 ...

  7. synchronized 异常_由浅入深,Java 并发编程中的 Synchronized

    synchronized 作用 synchronized 关键字是 Java 并发编程中线程同步的常用手段之一. 1.1 作用: 确保线程互斥的访问同步代,锁自动释放,多个线程操作同个代码块或函数必须 ...

  8. java 线程由浅入深_由浅入深,Java 并发编程中的 Synchronized(一)

    synchronized 作用 synchronized 关键字是 Java 并发编程中线程同步的常用手段之一. 1.1 作用: 确保线程互斥的访问同步代,锁自动释放,多个线程操作同个代码块或函数必须 ...

  9. java并发编程入门_探讨一下!Java并发编程基础篇一

    Java并发编程想必大家都不陌生,它是实现高并发/高流量的基础,今天我们就来一起学习这方面的内容. 什么是线程?什么是进程?他们之间有什么联系? 简单来说,进程就是程序的一次执行过程,它是系统进行资源 ...

  10. 由浅入深,逐步了解 Java 并发编程中的 Synchronized!

    作者 | sowhat1412  责编 | 张文 头图 | CSDN 下载自视觉中国 来源 | sowhat1412(ID:sowhat9094) synchronized 作用 synchroniz ...

最新文章

  1. 剑指offer:数字在排序数组中出现的次数
  2. Weblogic 集群部署说明 --转
  3. java字符串操作_Java的字符串操作
  4. 最小二乘与最大似然估计之间的关系
  5. python中 的用法_详解python中@的用法
  6. preempt_count
  7. mysql语句大全及例子_SQL语句大全实例教程.pdf
  8. 磁珠 符号_磁珠简介_磁珠的命名、单位和选型
  9. android nio wifi 拥堵 超时,提高WiFi上网速度,改变道路拥挤的方法
  10. linux系统mysql报err1055_MySQL Err 1055的解决
  11. PyCharm的安装与使用
  12. java 仿qq空间_仿QQ空间和微信朋友圈,高解耦高复用高灵活
  13. 二[2-(2,4-二氟苯基)-5-甲基吡啶][2,2‘-联(四叔丁基吡啶)]铱二(六氟磷酸)盐,1335047-34-1
  14. 科学计算模块Numpy-初级 (2)
  15. 跨时钟域的亚稳态处理、为什么要打两拍不是打一拍、为什么打两拍能有效?...
  16. 每日一练c++题目日刊 | 第七期
  17. 程序员展望未来八个小小技巧
  18. 对于LM法和信赖域的理解
  19. 记录一下黑窗打pak的指令
  20. 电子商务行业RFID仓库管理系统,智慧仓库管理RFID平台-新导智能

热门文章

  1. atitit 知识压缩的总结 学习方法总结v2 t55.docx 目录 1.1. 压缩目的 1 1.2. 压缩分类 无损压缩 有损压缩 1 2. 功能指标 2 2.1. 压缩比:有损压缩一般1
  2. java 队列总结queue v3 svv.docxjava 队列总结queue v3 svv.docx atitit. java queue 队列体系总结o7t 1. 队列概念 1 1.1. 队列
  3. Atitit attilax总结的对于attilax重要的jsr规范,以及需要增加的jsr规范
  4. Atitit. servlet 与 IHttpHandler  ashx  listen 和HttpModule的区别与联系 原理理论 架构设计   实现机制    java php c#.net j
  5. atitit. js 跨界面 页面 web cs 传值方法总结
  6. paip.论.NET体系的优缺点).txt
  7. paip.提升效率---------文件搜索工具总结
  8. 华锐研究:国际领先经营机构(投行)信息技术投入 | 数据发布
  9. Julia : 如何利用julia获取Joinquant web api的数据?
  10. 登录emc磁阵提示java版本低_安装完打开 eclipse 提示 JVM 版本较低