以前Synchronised关键字加锁效率问题,经常受到吐槽。后来java的开发团队进行了优化,引入了偏向锁、自旋锁、轻量锁,性能有了很大的提升。下面我们来分析下这里面的过程和原理。
 
     最初阶段,我们的代码段或者方法加syncronized关键字,如下:
syncronized(object) {
// do something
}

执行这段代码时,其实相当于,在这段代码前面加了monitorenter指令;后面加了monitorexit指令。如下:

 
 monitorenter
// do something
monitorexit
 
 这两指令都得和操作系统连接,相对来说是比较重的,比较耗时的。
 
但是,在代码里加synchronised 关键字时,只是全面考虑,很多情况只有一个线程在执行,如果在有这种情况下,就有些浪费了;另外,有时,即使多线程访问,他的等待时间是很短的,比monitorenter相关指令还轻,这也是可想办法优化的。
 
在叙述相关优化锁之前,我们先说下java 对象头部分的 Mark Word。在32位虚拟机上,他的长度是32位;在64位虚拟机上,他的长度是64位。
 
普通情况下,Mark Word的格式如下:
hash:25 ------------>| age:4    | biased_lock:1 lock:2
 
最后部分2个比特,是固定的,表示对象锁的状况
01 表示无锁,或者偏向锁; 00表示轻量级锁;10表示重量级锁
 
第三部分是标识是否偏向锁。当最后部分为01时,第三部分为0表示普通无锁对象,第三部分为1表示偏向锁;最后部分为其他值,第三部分不存在。
 
age表示分代年龄;hash表示对象hash值。
 
普通无锁:对象hash:25 ------------>| age:4    | 0 | 01
偏向锁:偏向锁的线程和时间戳:25 ------------>| age:4    | 1 | 01
轻量锁:指向栈中锁记录的指针:30  | 00
重量锁:指向互斥量(重量级锁)的指针:30 | 10
 
java1.6之后,对象有4中状态:无锁态,偏向锁态,轻量锁态,重量锁态。
 
java程序执行,没有遇到同步块时,都是无锁态。Mark Word如上普通无锁的情况。
 
遇到同步块之后,Mark Word从普通无锁变成偏向锁的情况,通过CAS加锁。如果是相同线程在次进入,不受影响。执行完成,CAS解锁,Mark Word又变成普通无锁的情况。
 
如果在偏向锁中,遇到锁竞争的情况。先线程停止,通过CAS锁升级到轻量锁,成功的一方继续执行,另一方开始自旋操作。待他完了继续执行。这里的自旋有个智能学习的策略。假设每个同步块的初始自旋次数是20次,A同步块的线程自旋时,每次很小的自旋次数就获得了执行时间,那后面他的自旋信用会很高,会超过20次往上升;B同步块的线程自旋时,每次都需要很大的自旋次数才能获得执行时间,后面就会把他的自旋次数从20往下降或者不给自旋机会。
 
当然,自旋失败后,锁得再次升级,通过CAS操作从轻量锁升级到重量锁,这就回到一开始的moniterenter指令和moniterexit指令了。
 
jvm还有其他一些锁的优化措施。
 
锁清除:在某些情况下,同步块中的代码不可能被其他线程访问修改的时候,这时候的锁是可以清除的。
锁粗化:在一些代码中,会频繁的加锁,加锁,加锁;当然,有时并不是程序员这么编写的,因为我们的jdk api中也会加些锁操作。我们得频繁的做互斥操作,可以把几个同步块合并成一个同步块来优化执行。
 
 
 

JVM锁说明的更多相关文章

  1. java多线程之:深入JVM锁机制2-Lock (转载)

    前文(深入JVM锁机制-synchronized)分析了JVM中的synchronized实现,本文继续分析JVM中的另一种锁Lock的实现.与synchronized不同的是,Lock完全用Java ...

  2. 转:synchronized和LOCK的实现原理---深入JVM锁机制

    JVM底层又是如何实现synchronized的? 目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug ...

  3. 深入JVM锁机制2-Lock

    前文(深入JVM锁机制-synchronized)分析了JVM中的synchronized实现,本文继续分析JVM中的另一种锁Lock的实现.与synchronized不同的是,Lock完全用Java ...

  4. 深入JVM锁机制1-synchronized

    目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug Lea.本文并不比较synchronized与Loc ...

  5. 终极锁实战:单JVM锁+分布式锁

    目录 1.前言 2.单JVM锁 3.分布式锁 4.总结 =========正文分割线================= 1.前言 锁就像一把钥匙,需要加锁的代码就像一个房间.出现互斥操作的场景:多人同 ...

  6. JVM锁简介:偏向锁、轻量级锁和重量级锁

    转自:https://www.aimoon.site/blog/2018/05/21/biased-locking/ 比较复杂,简略见另一篇:https://www.cnblogs.com/twohe ...

  7. [转载]深入JVM锁机制-synchronized

    转自:http://blog.csdn.net/chen77716/article/details/6618779,并加上少量自己的理解 目前在Java中存在两种锁机制:synchronized和Lo ...

  8. [转帖]B4. Concurrent JVM 锁机制(synchronized)

    B4. Concurrent JVM 锁机制(synchronized) https://www.cnblogs.com/zlxyt/p/11050346.html 挺好的 感觉这个文章写的 不过想要 ...

  9. java源码剖析: 对象内存布局、JVM锁以及优化

    一.目录 1.启蒙知识预热:CAS原理+JVM对象头内存存储结构 2.JVM中锁优化:锁粗化.锁消除.偏向锁.轻量级锁.自旋锁. 3.总结:偏向锁.轻量级锁,重量级锁的优缺点. 二.启蒙知识预热 开启 ...

  10. JVM锁机制之synchronized

    概述: synchronized是java用于处理多线程同步的一个关键字,用于标记一个方法/代码块,使之成为同步方法/同步块. 用synchronized可以避免多线程处理时的竞态条件问题. 相关概念 ...

随机推荐

  1. BasePage基础页面的封装

    Paget Object设计模式,不多说,但在接触了poium测试库后,个人感觉BasePage都是多余的..但在次还是做个记录 class Page(): def __init__(self, dr ...

  2. vue ts ,vue使用typescript,三种组件传值方式

    参考链接:https://juejin.im/post/5c55156f6fb9a049ef270541

  3. 12.Flume的安装

    先把flume包上传并解压 给flume创建一个软链接 给flume配置环境变量 #flume export FLUME_HOME=/opt/modules/flume export PATH=$PA ...

  4. 2019-07-30 C#基础知识学习

    继承和多态 接口与抽象类的区别:1.在接口中仅能定义成员,但是不能有具体的实现:抽象类除了抽象成员以外,其他成员有具体的实现.2.在接口中不能声明字段,并且不能声明任何私有成员,成员不能包含任何修饰符 ...

  5. SQLite基础-7.子句(一)

    目录 SQLite子句(一) 1. WHERE子句 2. LIKE子句 3. GLOB 子句 4. Oreder By 子句 SQLite子句(一) 1. WHERE子句 WHERE 子句后面跟着条件 ...

  6. PAT A1002 A+B for Polynomials(25)

    AC代码 转载自https://www.cnblogs.com/zjutJY/p/9413766.html #include <stdio.h> #include<string.h& ...

  7. pyton 类(4) 静态方法

    class Cat(): tag = ' 猫科动物 ' def __init__(self, name): self.name = name @staticmethod def breah(): pr ...

  8. pytest参数化的两种方式

    1.传统方式 import requests,pytest from Learning.variable import * # 定义变量 #url = "https://www.baidu. ...

  9. python3爬虫图片验证码识别

    # 图片验证码识别 环境安装# sudo apt-get install -y tesseract-ocr libtesseract-dev libleptonica-dev# pip install ...

  10. eclipse设置字体