Chao's Blog Chao's Blog
首页
  • vue

    • vue路由
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • java
  • spring
  • springboot
  • springcloud
  • git
  • maven
  • nginx
  • tomcat
  • springmvc
  • jvm
  • 图数据库
  • mysql数据库
  • redis数据库
  • windows下docker安装nginx并挂载目录
  • linux命令
  • linux安装软件
  • linux脚本
  • idea
  • vscode
  • 归档
  • 综合项目

    • 若依项目
    • mall项目
  • java
  • mybatis
  • xxl-job
  • mybatis
GitHub (opens new window)

~chao

永远菜鸟,不断努力~
首页
  • vue

    • vue路由
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • java
  • spring
  • springboot
  • springcloud
  • git
  • maven
  • nginx
  • tomcat
  • springmvc
  • jvm
  • 图数据库
  • mysql数据库
  • redis数据库
  • windows下docker安装nginx并挂载目录
  • linux命令
  • linux安装软件
  • linux脚本
  • idea
  • vscode
  • 归档
  • 综合项目

    • 若依项目
    • mall项目
  • java
  • mybatis
  • xxl-job
  • mybatis
GitHub (opens new window)
  • java

    • java深度克隆
    • restemplate

    • hashcode()和equals()的作用、区别、联系
    • java8新特性
    • 接口与抽象类
    • java深度克隆工具类支持对象和list克隆
    • 子线程执行10次后,主线程再运行5次,这样交替执行三遍
    • CountDownLatch的理解和使用
    • CAS详解
    • java中的各种锁详细介绍
    • java线程池
    • Java锁之偏向级锁、轻量级锁、重量级锁
      • Transactional注解与try{}catch(Exception e){}同时使用事务控制无效问题
      • JAVA8 optional用法
      • CyclicBarrier 使用详解
      • Semaphore 使用及原理
      • Java中七大垃圾回收器
    • spring

    • springboot

    • springcloud

    • git

    • maven

    • nginx

    • tomcat

    • springmvc

    • jvm

    • 正则表达式

    • 消息中间件

    • python

    • 后端
    • java
    ~chao
    2023-02-15
    目录

    Java锁之偏向级锁、轻量级锁、重量级锁

    # Java锁之偏向级锁、轻量级锁、重量级锁

    原文链接:(30条消息) Java锁之偏向级锁、轻量级锁、重量级锁_Colourful.的博客-CSDN博客_偏向级锁 (opens new window)

    # 文章目录

    • 什么是偏向级锁、轻量锁、重量级锁 (opens new window)
    • 偏向级锁 (opens new window)
    • 轻量级锁 (opens new window)
    • 重量级锁 (opens new window)

    # 什么是偏向级锁、轻量锁、重量级锁

        首先,我们需要明确一点:**这三种锁只针对synchronized**
    
        我们都知道,任意一个java对象都可以做为锁,java对象的锁信息存储在对象头中的Mark Word字段中。Mark Word里默认存储对象的HashCode、分代年龄和锁标记位。32位JVM的Mark Word的默认存储结构如下图:  
    

    在这里插入图片描述 Java中锁主要存在四种状态:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态,随着竞争的激烈而逐渐升级。锁只能升级而不能降级,即一个锁从偏向级锁升级到轻量锁时,不能再重新回到偏向级锁。

    # 偏向级锁

        顾名思义,偏向某一个线程,当线程数目不多的时候,由于反复获取锁会使得我们的运行效率下降,于是出现了偏向级锁。JVM使用CAS操作把线程ID记录到对象的Mark Word当中,并修改标识位,name当前线程就拥有了这把锁。  
    

    在这里插入图片描述
    偏向级锁不需要操作系统的介入,JVM使用CAS操作将线程ID放入对象的Mark Word字段中,于是线程获得了锁,可以执行synchronized代码块的内容,当线程再次执行到这个synchronized的时候,JVM通过锁对象的Mark Word判断 :当前线程ID还存在,还持有这个对象的锁,于是就可以继续进入临界区执行,而不需要再次获得锁

        偏向锁,在没有别的线程竞争的时候,一直偏向当前线程,当前线程就可以一直进入synchronized修饰的代码块一直运行。
    
        如果在运行中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会消除它身上的偏向锁,将锁升级到轻量级锁。
    
        **总结一点**:偏向级锁就是为了消除资源无竞争情况下的同步原语,进一步提高了程序的运行性能。
    

    # 轻量级锁

        轻量级锁是由偏向级锁升级来的,当一个线程运行同步代码块时,另一个线程也加入想要运行这个同步代码块时,偏向锁就会升级为轻量级锁。
    
        首先,JVM会将锁对象的Mark Word恢复成为无锁状态,**在当前两线程的栈桢中各自分配一个空间,叫做Lock Record,把锁对象account的Mark Word在两线程的栈桢中各自复制了一份,官方称为:Displaced Mark Word**  
    

    在这里插入图片描述

        然后一个线程尝试使用CAS将对象头中的Mak Word替换为指向锁记录的指针,如果替换成功,则当前线程获得锁,如果失败,则当前线程**自旋**重新尝试获取锁。当自旋获取锁仍然失败时,表示存在其他线程竞争锁(两个或两个以上线程竞争同一个锁),**则轻量级锁会膨胀成重量级锁**
    
        举个例子: 线程A、线程B同时想要执行一个同步代码块,假设线程A抢到了锁,则线程A的Lock Record的地址 会被CAS操作放到了锁对象Mark Word中,并且将锁标志位改为00,这意味着线程A就获取到了该锁,可以执行同步代码块。
    
        而线程B没有抢到锁,但是**线程B不会阻塞,而是通过自旋的方式,等待获取锁。(一般默认自旋10次)**,如果线程A释放掉锁,则将线程A中的Displaced mark word使用CAS复制回锁对象的Mark Word字段,此时线程B就可以获取锁对象,如果线程B还没有获取成功,则说明同时存在两个或两个以上的线程同时竞争这一把锁,**轻量级锁会升级成为重量级锁**。
    

    # 重量级锁

        我们上面提到,当多个线程竞争同一个锁时,会导致除锁的拥有者外,其余线程都会自旋,这将导致自旋次数过多,cpu效率下降,所以会将锁升级为重量级锁。
    
        **重量级锁需要操作系统的介入,依赖操作系统底层的Muptex Lock**。JVM会创建一个monitor对象,把这个对象的地址更新到Mark Word中。  
    

    在这里插入图片描述

        **当一个线程获取了该锁后,其余线程想要获取锁,必须等到这个线程释放锁后才可能获取到,没有获取到锁的线程,就进入了阻塞状态。**
    编辑 (opens new window)
    上次更新: 2024/01/26, 05:03:22
    java线程池
    Transactional注解与try{}catch(Exception e){}同时使用事务控制无效问题

    ← java线程池 Transactional注解与try{}catch(Exception e){}同时使用事务控制无效问题→

    最近更新
    01
    python使用生成器读取大文件-500g
    09-24
    02
    Windows环境下 Docker Desktop 安装 Nginx
    04-10
    03
    使用nginx部署多个前端项目(三种方式)
    04-10
    更多文章>
    Theme by Vdoing | Copyright © 2022-2024 chaos | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式