java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java Synchronize底层原理

Java Synchronize底层原理总结

作者:EzreaLwj

这篇文章主要给大家总结了Java Synchronize底层原理,文中的图文讲解介绍的非常详细,对我们学习Java Synchronize有一定的帮助,需要的朋友可以参考下

对象内存结构

对象头MarkWord 存储对象头的信息,Klass Word 描述对象实例的具体类型

实例数据:成员变量

对齐填充:如果对象头 + 实例变量 不是 8 的整数倍,则通过对齐填充补齐

MarkWord 解析

LockRecord 锁记录

Markword:记录锁记录的地址

对象引用:引用被加上锁了的对象

重量级锁

Monitor

Monitor 监视器,是由 jvm 提供的,由 C++ 实现的,有三个实现部分

WaitSet:调用了 wait 方法的线程在这里等待,处于 WAITED 状态

EntryList:没有抢到对象锁的线程在这里等待,处于 BLOCKED 状态

Owner:存储已经抢到锁的线程对象

Monitor 的实现属于重量级锁,涉及到 内核态和用户态的切换线程的上下文切换,每个 Java 对象都会关联一个 Monitor 对象,如果使用 Synchronize 给该对象加锁,那么 Java 对象上面的 MarkWord 地址就被设置为指向该 Monitor 对象的指针

轻量级锁

加锁流程

解锁过程

Markword 记录

开始时的状态

替换后的状态

偏向锁

背景:轻量级锁在没有竞争的时候,每次重入都需要进行 CAS 操作

Java 6 中 引入偏向锁来做进一步的优化:只有第一次 操才使用 CAS 将线程 ID 设置到对象的 markword 头,之后发现这个线程 ID 是自己就不会产生竞争,不用重新 CAS,以后只要不发生竞争,这个对象就归这个线程所有

代码示例:

public class Thread5 {
    private static final Object object = new Object();
    public static void method1() {
        synchronized (object) {
            method2();
        }
    }
    public static void method2() {
        synchronized (object) {
            method3();
        }
    }
    public static void method3() {
        synchronized (object) {
        }
    }
}

总结

Java 中的 Synchronize 有偏向锁、轻量级锁、重量级锁三种形式,分别对应了锁只被一个线程持有、不同线程交替持有锁、多线程竞争的情况

重量级锁:底层使用 Monitor 实现,里面涉及到了用户态和内核态的转换、进程的上下文切换,成本较高,性能比较低

轻量级锁:线程加锁时间是错开的(也就是没有竞争),可以用轻量级锁来优化,轻量级修改了对象头的锁标志,相对重量级锁性能提升了许多,每次修改都是 CAS 操作,保证原子性

偏向锁:一段很长的时间内都只被一个线程使用锁,可以使用偏向锁,第一次获得锁时,会有一个 CAS 操作,之后该线程再获取锁,只需要判断 mark word 中是否是自己的线程 id 即可,而不是开销相对较大的 CAS 命令

以上就是Java Synchronize底层原理总结的详细内容,更多关于Java Synchronize底层原理的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文