zoukankan      html  css  js  c++  java
  • synchronized原理

       synchronized是单服务器常用的同步机制,可是具体的原理又有多少人能说清呢?

       synchronized既可以用于同步一个代码块,又可以同步一个类和方法:

       当作用于一个静态类时,所有调用到静态类的地方都会被同步;

       当作用于一个普通类时,所有调用到类实例的地方会被同步;

       当同步于一个方法区时,所有调用到括号中的对象会被同步;

         

          JVM中是通过进入和退出Monitor对象来实现线程同步的,对于同步方法区来说,主要是通过monitorenter 和monitorexit指令来实现的,而方法同步的则是通过另一种方式实现的,当然也可以用monitorenter 和monitorexit来实现。   monitorenter指令是在编译后插入方法区开头,monitorexit指令是插入到方法结束处或者异常处,JVM要求monitorenter和monitorexit都必须成对出现。

          每个对象都有一个monitor与之关联,当线程持有该monitor时,其它线程无法访问对象。synchronized 对象用到的锁是存在Java对象头中的,32位虚拟机中,Java对象头结构一般如下

    长度   内容   说明
    32bit Mark Word 对象的hashCode或者锁信息
    32bit Class Metadata Address 存储到对象类型数据的指针
    32bit Array length 数组长度(如果是数组)

      

           其中Mark Word存储格式如下

    锁状态   25bit 4bit 1bit是否偏向锁 2bit 锁标识

    无锁/偏向锁/

    轻量级锁/重量级锁

    对象hashcode  对象分代年龄  0  

    00-轻量级锁

    01-偏向锁

    10-重量级锁

    11-GC标识

    •         偏向锁

       当某个线程1访问同步块时,如果对象头没有存储当前线程,则通过CAS替换Mark word,如果替换成功,则将对象头Mark word线程ID指向自己,这时候如果另一个线程2开始访问同步块,则CAS替换Mark word会失败,线程2则会撤销偏向锁暂停线程。线程1执行完同步块后会释放锁,将Mark word中的线程ID设为空,其它线程可进行访问同步块。

    •         轻量级锁/重量级锁 

          与偏向锁通过控制Mark word指向线程ID的方式不同,轻量级锁实现原理如下:

          当线程访问同步块时,会在线程的栈桢中创建锁记录空间,将对象头中的Mark word复制到锁记录中。当线程访问同步块时,会使用CAS将对象头中的 Mark word复制到自己线程的锁记录空间中,当获取成功后,当前线程获取到锁,如果失败,则说明线程已被其他线程竞争得到,当前线程会通过自旋获取锁。竞争锁成功的线程在执行完同步块后会通过CAS替换Mark word,当替换失败后,表明当前锁存在竞争,锁将会自动升级为重量级锁,其余通过自旋竞争锁的线程将被阻塞,直至锁释放后被唤醒。

  • 相关阅读:
    2020面试有感(1)
    多线程与异步
    GP-荧光免疫分析仪SDK 协议
    FastReport模板设计和调用
    EF的多线程与分库架构设计实现(2)
    HTML页面转化为带有水印的PDF文件
    利用 html2canvas+jsPDF 把 HTML元素 转化为PDF文件,以及遇到的坑
    前端json数据格式化显示
    单元测试——引入Vuex
    单元测试——引入vue-router和APP.vue文件
  • 原文地址:https://www.cnblogs.com/toDjlPersonnalBlog/p/8280961.html
Copyright © 2011-2022 走看看