synchronized原理

本文详细介绍了Java中synchronized的工作原理,包括锁的对象、对象头的结构、monitor的实现,以及synchronized的优化机制,如偏向锁、轻量级锁和自旋锁等。通过对synchronized的深入理解,有助于优化多线程代码的性能。
摘要由CSDN通过智能技术生成

synchronized到底锁的是什么

可分为三种情况
记住:synchronized不可以锁静态代码快
1.代码块
此时锁的是括号中的变量/类,一般我们习惯写成this,此时锁的是当前类的实例化对象,如果多个线程用的是一个实例化对象,此时就一个线程拿到锁,其他线程无法访问,但是如果是每个线程都用每个线程实例化的对象,此时就不会线程线程同步。

2.普通方法
此时synchronized锁的是调用该方法的对象
3.静态方法
此时锁的是该方法所在的类
monitor结构:

在这里插入图片描述

要想理解的原理首先需要理解对象头

在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充

实例变量:存放类的属性数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分内存按4字节对齐。

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

对象头:
1.运行时元数据:哈希值,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳
2.类型指针,指向类元数据InstanceKlass,确定对象所属类型
3.如果是数组,还需要记录数组的长度

synchronized使用的锁对象是存储在Java对象头里的
其中Mark Word在默认情况下存储着对象的HashCode、分代年龄、锁标记位等以下是64位JVM的Mark Word默认存储结构
在这里插入图片描述
每个对象都存在着一个 monitor 与之关联,对象与其 monitor 之间的关系有存在多种实现方式,如monitor可以与对象一起创建销毁或当线程试图获取对象锁时自动生成,但当一个 monitor 被某个线程持有后,它便处于锁定状态。在Java虚拟机(HotSpot)中,monitor是由ObjectMonitor实现的,其主要数据结构如下 (位于HotSpot虚拟机源码ObjectMonitor.hpp文件,C++实现的)

objectMoniter结构

ObjectMonitor() {
   
    _header       = NULL;
    _count        = 0; //记录个数
    _waiters      = 0<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值