您的位置:首页 > 编程语言 > Java开发

Synchronized使用、 java对象在JVM内存模型中的构成、 synchronized同步代码块的底层原理、 synchronized同步方法的底层原理

2020-08-08 15:14 155 查看

文章目录

参考

https://blog.csdn.net/qq_35190492/article/details/106180781
https://www.cnblogs.com/lukelook/p/9946065.html
https://baijiahao.baidu.com/s?id=1612142459503895416

Synchronized 使用

  • 修饰方法
public synchronized void method(){

}

synchronized 关键字不能继承。

  • 修饰代码块
synchronized(this){

}
synchronized(obj){

}

当一个线程访问一个对象中的 synchronized(this) 同步代码块时,其他试图访问该对象的线程将被阻塞(多个线程可以访问同一个对象,this 指当前对象)

用 synchronized 给 obj 对象加锁,当一个线程访问 obj 对象时,其他试图访问 obj 对象的线程将会阻塞

  • 修饰类
synchronized(MyClass.class)

该类的所有对象公用一把锁

java对象在 JVM内存模型 中的构成

  • 对象头

    Mark Word(标记字段)
    默认存储对象的 HashCode分代年龄锁标志位信息。它会根据对象的状态复用自己的存储空间,也就是说在运行期间Mark Word里存储的数据会随着锁标志位的变化而变化。

  • Klass Point(类型指针)
    对象指向它的 元数据的指针,虚拟机通过这个指针来确定这个对象是 哪个类的实例。

  • 实例数据
    这部分主要是存放类的数据信息,父类的信息。

  • 对齐填充
    由于虚拟机要求对象起始地址必须是8字节的整数倍,填充数据不是必须存在的,仅仅是为了字节对齐。

  • 一个空对象占多少个字节?就是8个字节,是因为对齐填充的关系,不到8个字节对其填充会帮我们自动补齐。

    synchronized 同步代码块 的底层原理

    synchronized 锁住对象,其指针指向该对象的 monitor

    每个对象实例都会有一个 monitor。其中 monitor 可以与对象一起创建、销毁;或者当线程试图获取对象锁时自动生成。

    monitor是由 ObjectMonitor 实现(ObjectMonitor.hpp文件)(.hpp 是 C++ 的头文件后缀)

    _WaitSet 用来保存每个等待锁的线程对象。
    _owner,它指向持有ObjectMonitor对象的线程。

    当多个线程同时访问一段同步代码时,会先存放到 _EntryList 集合中,接下来当线程获取到对象的 monitor 时,就会把 _owner 变量设置为当前线程。同时 count变量+1。

    如果线程调用wait() 方法,就会释放当前持有的monitor,那么 _owner 变量就会被置为null,同时 _count减1,并且该线程进入 WaitSet集合中,等待下一次被唤醒。

    因为这个锁对象存放在对象本身,也就是为什么Java中任意对象可以作为锁的原因。

    字节码中在执行 monitorenter 指令时,首先要尝试获取对象锁,也就是上文提到的 monitor 对象。如果这个对象没有被锁定,或者当前线程已经拥有了这个对象的锁,那么就把锁的计数器(_count)加1。当然与之对应执行 monitorexit 指令时,锁的计数器(_count)也会减1。

    如果当前线程获取锁失败,那么就会被阻塞住,进入 _WaitSet 中,等待锁被释放为止。

    字节码中,有俩个 monitorexit 指令的原因是:编译器需要确保方法中调用过的每条 monitorenter 指令都要执行对应的monitorexit 指令。为了保证在方法异常时,monitorenter和monitorexit指令也能正常配对执行,编译器会多写一个 monitorexit 指令

    synchronized 同步方法 的底层原理

    字节码中并没有 monitorenter指令和 monitorexit指令,取得代之的是 ACC_SYNCHRONIZED 标识

    JVM通过 ACC_SYNCHRONIZED 标识,就可以知道这是一个需要同步的方法,进而执行上述同步的过程,也就是 _count加1 的这些过程。

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: 
    相关文章推荐