zoukankan      html  css  js  c++  java
  • Java精通并发-锁升级与偏向锁深入解析

    对于synchronized关键字,我们在实际使用时可能经常听说用它是一个非常重的操作,其实这个“重”是要针对JDK的版本来说的,如今JDK已经到了12版本了,其实对这个关键字一直是存在偏见的,它底层也发生了很多的变化,所以我们也得随着JDK的版本将知识进行更新才行,所以这节继续针对锁进行深入的探讨。

    在JDK 1.5之前,我们若想实现线程同步,只能通过synchronized关键字这一种方式来达成;底层,Java也是通过synchronized关键字来做到数据的原子性维护的;synchronized关键字是JVM实现的一个内置锁,从底层角度来说,这种锁的获取和释放都是由JVM帮助我们隐式实现的。

    在JDK 1.5开始,并发包引入了Lock锁,如:

    其中有很多子类的实现,有一个比较常用的锁是可重入锁,如下:

    ,Lock同步锁是基于Java来实现的,因此锁的获取与释放都是通过Java代码来实现与控制的;然而synchronized是基于底层操作系统的Mutex Lock来实现的,每次对锁的获取与释放动作都会带来用户态与内核态之间的切换,这种切换会极大地增加系统的负担;在并发量较高时,也就是说锁的竞争比较激烈的时候,synchronized锁在性能上的表现就非常差【这也是很多人认为使用synchronized关键字的性能不太好的原因】。

    但是!!从JDK1.6开始,synchronized锁的实现发生了很大的变化;JVM引入了相应的优化手段来提升synchronized锁的性能,这种提升涉及到偏向锁、轻易级锁、重量级锁等,从而减少锁的竞争所带来的用户态与内核态之间的切换;这种锁的优化实际上是通过Java对象头【这个在JVM的学习中已经学习过了】中的一些标志位来去实现的;对于锁的访问与改变,实际上都与Java对象头息息相关。

    从JDK 1.6开始,对象实例在堆当中会被划分为三个组成部分:对象头、实例数据与对齐填充。

    对象头主要也是由三块内容构成:

    1、Mark Word【这是我们现在要探讨的东东】

    2、指向类的指针

    3、数组长度

    其中Mark Word(这记录了对象、锁及垃圾回收相关的信息,在64位的JVM中,其长度也是64bit)的位信息包括了如下组成部分: 

    1、无锁标记

    2、偏向锁标记

    3、轻量级锁标记

    4、重量级锁标记【这就是通常意义上我们理解的synchronized的情况,认为它是很重的,从用户态转向内核态】

    5、GC标记

    对于synchronized锁来说,锁的升级主要是通过Mark Word中的锁标志位与是否是偏向锁标志位来达成的;synchronized关键字所对应的锁都是先从偏向锁开始,随着锁竞争的不断升级,逐步演化至轻量级锁,最后则变成了重量级锁。

    对于锁的演化来说,它会经历如下阶段:

    无锁  ->   偏向锁  ->   轻量级锁  ->   重量级锁

  • 相关阅读:
    数位DP入门
    划分树
    CodeForces #362 div2 B. Barnicle
    CodeForces #363 div2 Vacations DP
    CodeForces #368 div2 D Persistent Bookcase DFS
    解决Ubuntu 下 vi编辑器不能使用方向键和退格键问题
    python之爬虫爬有道词典
    hdu 5145 NPY and girls 莫队
    hdu 6185 Covering 矩阵快速幂
    字典树求异或值
  • 原文地址:https://www.cnblogs.com/webor2006/p/11446129.html
Copyright © 2011-2022 走看看