zoukankan      html  css  js  c++  java
  • 【JDK源码】Synchronized关键字原理,和锁的膨胀过程

    Synchronized关键字原理,和锁的膨胀过程

    一:Synchronized关键字介绍

    synchronized是Java中的关键字,用于线程的同步。可以用在三个地方。

    ​ 1:同步实例方法,锁是当前实例对象;

    ​ 2:同步类方法,锁是当前类对象;

    ​ 3:同步代码块,锁是括号里面的对象;

    二:Synchronized的原理解析

    1:synchronized是JVM内置锁,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,监视器锁的实现依赖底层操作系统的Mutex lock(互斥锁)实现。

    我们对Synchronized的代码进行编译成字节码文件后,可以看到

    public class SynchronizedDemo {
      
      private final Object object = new Object();
      @Test
      public void test01() {
        synchronized (object) {
          System.out.println("true = " + true);
        }
      }
    }
    

    比如这段代码,我们锁的object对象,但是jvm怎么实现锁定对象的呢?

    首先我们认识一下对象在jvm里面内存结构。

    JVM锁的膨胀过程

    内存中java对象是通过mark word在记录锁的状态。分表记录了轻量级锁,重量级锁,偏向锁,无锁的四种状态。

    通过锁的标记位标记锁的状态。

    比如现在线程T1进入获取锁的代码,首先判断这个锁对象(如:标记的object对象)首先检查锁的标志位,如果是01,然后再判断是否未偏向锁,检查标记是否未偏向锁的bit位是否位1,如果是1的话当前对象处于就是偏向锁,如果是0的话就是无锁状态,无锁的话,通过CAS修改锁的状态位偏向锁。

    这个时候线程T2来获取锁,首先检查当前锁的状态,此时处于偏向锁状态。然后判断当前占用锁的线程ID是否位为自己。明显当前偏向锁的占有者是t1线程

    这时候,t2线程会尝试 通过CAS修改,这个CAS循环获取锁的此时jvm可以有限制的,再指定次数获取失败后。

    就说检查当前占用锁的t1线程是否走完同步代码块,如果走完了,设置当前占用锁的线程id为null。这个时候线程t2就可以获取到锁了。

    如果t1没有走完同步代码块,还在进行同步逻辑。这个时候偏向锁就会升级为偏向锁,将锁的标记为设置为00(前面图中所示)。

    这个时候锁的标记位如下图。

    这个时候我们的t1线程,在线程栈占用开辟一块空间,执行我们的锁对象,同时锁对象中的Mark word中也会有空间指针指向,t1线程栈中的空间。如下图所示。

    这个时候t2同样没有获取到锁,这时候t2同样通过CAS(一定次数)修改mark word中轻量级锁的指针。假如继续获取失败。

    锁就会继续膨胀升级位重量级锁。这个时候锁的Mark word 如下图

    这个时候,锁就进入了java6以前版本的模式了。t2就会被阻塞挂起来,等t1执行结束后重新被唤醒。

    synchronized是JVM内置锁,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,监视器锁的实现依赖底层操作系统的Mutex lock(互斥锁》实现

    总结

    synchronized在java6 以后做了升级,性能不输我们java.util.concurrent包中的lock锁。同时我们看Synchronized原理知道,我们在用Synchronized关键字同步代码块的时候,锁定的范围尽量小,执行的时间尽量控制短一些。不然锁容易膨胀,性能就会下降。

  • 相关阅读:
    IIS配置ThinkPHP重写
    Redis安装
    ubuntu学习笔记
    PHP连接MySQL数据库SELinux中一些setsebool的用法
    centos+frp
    centos7.6安装nginx
    在CentOS 7-8上安装PHP 8.0
    centos7安装.net5.0(core)
    阿里云服务器配置清单
    阿里云服务器centos7.6安装mysql8.0.23
  • 原文地址:https://www.cnblogs.com/simple-flw/p/14772927.html
Copyright © 2011-2022 走看看