原创

对于Java中 Synchronized的一些理解


       在多线程环境中synchronized和volatile都扮演着重要的角色,volatile是轻量级的synchronized,它在多个处理器开发中保证了共享变量的可见性。可见性的意思是 当一个线程修改一个共享变量,另外一个线程能读到这个修改的值。它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。

    volatile的应用

    有volatile修饰的共享变量进行写操作时会多出 一条 加 lock前缀的汇编代码,Lock前缀的指令在多核处理器下会引发两件事情:

(1)将当前处理器缓存行的数据写入系统内存

(2)这个写会内存的操作会使其他CPU里缓存了该内存地址的数据无效

 

    synchronized的实现原理和应用

synchronized实现同步的基础:Java中的每一个对象都可以作为锁。具体表现在以下三种形式:

    (1)对于普通的方法,锁是当前实例对象

    (2)对于静态同步方法,锁是当前类的Class对象

    (3)对于方法块,锁是synchronized括号里配置的对象

当一个线程视图访问同步代码块时,它首先必须得到锁,退出或者抛出异常时必须释放锁。


    Synchronized在JVM里的实现原理:

     JVM基于进入和退出Monitor对象来实现方法同步和代码块同步,但两者的实现细节不一样。代码块同步是使用monitorenter和monitorexit指令实现的,而方法同步是使用另外一种方式实现的,jvm规范中没有详细说明。

    monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束和异常出,JVM要保证每个monitorenter必须要有对应的monitorexit与之配对。任何对象都有一个monitor与之关联,当且一个Monitor被持有后,它将处于锁定状态。线程执行到monitorenter指令后,将会尝试获取对象所对应的Monitor的所有权,即尝试获得对象的锁。

    synchronized用的锁是存在Java对象头里的。

 

    JavaSE1.6 为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”,锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态重量级锁状态,这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降为偏向锁。锁只能升级不能降级的策略,目的是为了提高获得锁和释放锁的效率。

 

     对于偏向锁,轻量级锁另外探讨。

Java