synchronized 与 volatile 的实现原理

1、synchronized 原理

    无论是 synchronized 方法还是 synchronized 代码块,都是基于 monitor 对象实现的

1.1 synchronized 方法

    synchronized 方法在 method_info 结构有 ACC_SYNCHRONIZED 标记,JVM 就是根据该标示符来实现方法的同步的 当方法调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,如果设置了,执行线程将先获取 monitor 对象,获取成功之后才能执行方法体,执行完后释放 monitor。 在方法执行期间,其他任何线程都无法再获得同一个 monitor 对象

1.2 synchronized 代码块

    在编译字节码的时候,代码块起始的地方插入 monitorenter 指令,异常和代码块结束处插入 monitorexit 指令,线程在执行 monitorenter 指令的时候尝试获取 monitor 对象的所有权,获取不到的情况下就是阻塞。

2、volatile 原理

JMM 层面的“内存屏障”:

LoadLoad 屏障: 对于这样的语句 Load1; LoadLoad; Load2,在 Load2 及后续读取操作要读取的数据被访问前,保证 Load1 要读取的数据被读取完毕。 StoreStore 屏障:对于这样的语句 Store1; StoreStore; Store2,在 Store2 及后续写入操作执行前,保证 Store1 的写入操作对其它处理器可见。 LoadStore 屏障:对于这样的语句 Load1; LoadStore; Store2,在 Store2 及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。 StoreLoad 屏障: 对于这样的语句 Store1; StoreLoad; Load2,在 Load2 及后续所有读取操作执行前,保证 Store1 的写入对所有处理器可见。
    JVM 的实现会在 volatile 读写前后均加上内存屏障,在一定程度上保证有序性。如下所示:
LoadLoadBarrier volatile 读操作 LoadStoreBarrier
StoreStoreBarrier volatile 写操作 StoreLoadBarrier

    参考资料: https://www.cnblogs.com/yaowen/p/11240540.html
经验分享 程序员 微信小程序 职场和发展