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

    synchronized内置锁是一种对象锁(锁的是对象而非引用),作用粒度是对象,可以用来实现对共享资源的同步互斥访问,是可重入的。

    synchronized访问修饰特点:
    1、修饰普通方法,持有的对象锁,锁的是实例对象
    2、修饰静态方法,持有的class锁,锁的是class类的所有实例,即不同class实例对象调用synchronized static修饰的不同方法,执行结果是同步的。
    3、对于同步方法块,锁是Synchronized括号里配置的对象
    4、锁可重入

    synchronized实现原理:
    是基于JVM内置锁实现,通过内部对象Monitor是基于JVM内置锁实现,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,监视器锁的实现依赖底层操作系统的Mutex lock(互斥锁)实现,它是一个重量级锁性能较低。

    synchronized同步获取对象锁(重量级锁)过程:
    JVM基于进入和退出Monitor对象来实现方法同步和代码块同步。代码块同步是使用monitorenter和monitorexit指令实现的,monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处。任何对象都有一个monitor与之关联,当且一个monitor被持有后,它将处于锁定状态。
    根据虚拟机规范的要求,在执行monitorenter指令时,首先要去尝试获取对象的锁,如果这个对象没被锁定,或者当前线程已经拥有了那个对象的锁,把锁的计数器加1;相应地,在执行monitorexit指令时会将锁计数器减1,当计数器被减到0时,锁就释放了。如果获取对象锁失败了,那当前线程就要阻塞等待,直到对象锁被另一个线程释放为止。

    synchronized性能优化过程
    jdk1.6之前是直接获取重量级锁,性能低下的原因是JVM运行是用户态下,运行重量级锁的同步代码块需要切换到内核态,在状态切换过程中及影响性能。
    1.6及其之后对synchronized实现进行优化有了锁升级,重最开始new --> 偏向锁 --> 轻量级锁(自旋锁) -->重量级锁。

    对象锁的四种状态
    new(无锁)、偏向锁、轻量级锁(自旋锁)、重量级锁

    锁升级过程(锁膨胀):
    偏向锁:只有一个线程运行同步代码时使用。

    轻量级锁:当开始发生竞争时使用。
    竞争锁的方式:在A、B各自的线程栈中创建LockRecord对象,如果A线程抢到轻量级锁,那么锁中保存指向lockrecord的指针。
    通过CAS方式获取,会占用CPU,如果有多个线程自旋等待会提高CPU的使用率,为了避免CPU占用过高,会把轻量级锁升级为重量级锁。

    重量级锁:当发生激烈竞争时使用。升级为重量级锁后,操作系统实现线程之间的切换时需要从用户态转换到核心态,这个过程及其影响性能。
    线程获取锁的方式:当升级为重量级锁之后,等待执行的线程会被放到队列中等待执行,处于阻塞状态,不会占用CPU,有效降低CPU使用率。

    synchronized对象锁状态变化理解所需工具:jol-core(Java Object Layout)

    —转载请注明出处
  • 相关阅读:
    Sql Server中暂停命令
    优化SQL Sever查询语句的几个要点
    SQL Server 常用日期查询语句
    Android开发环境配置
    java实验报告(实验一)
    java实验报告(实验二)
    学习java的一点体会
    [已解决]求助:vs2003用代码实现excel的设置
    关于webform信息提示框
    DataGrid按钮事件的触发
  • 原文地址:https://www.cnblogs.com/landiss/p/14195210.html
Copyright © 2011-2022 走看看