锁(一)synchronized的基本原理

synchronized的基本应用

synchronized有三种方式来加锁,不同的修饰类型,代表锁的控制粒度:

  1. 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
  2. 静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
  3. 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。

锁的实现模型理解

Synchronized到底帮我们做了什么,为什么能够解决原子性呢?

在没有加锁之前,多个线程去调用incr()方法时,没有任何限制,都是可以同时拿到这个i的值进行++ 操
作,但是当加了Synchronized锁之后,线程A和B就由并行执行变成了串行执行。
在这里插入图片描述

Synchronized的原理

Synchronized是如何实现锁的,以及锁的信息是存储在哪里? 就拿上面分析的图来说,线程A抢到锁
了,线程B怎么知道当前锁被抢占了,这个地方一定会有一个标记来实现,而且这个标记一定是存储在
某个地方。

Markword对象头

这就要引出Markword对象头这个概念了,它是对象头的意思,简单理解,就是一个对象,在JVM内存
中的布局或者存储的形式。

jdk8u: markOop.hpp
在Hotspot虚拟机中,对象在内存中的存储布局,可以分为三个区域:对象头(Header)、实例数据
(Instance Data)、对齐填充(Padding)

在这里插入图片描述
MarkWord结构如下
在这里插入图片描述
mark-word:对象标记字段占4个字节,用于存储一些列的标记位,比如:哈希值、轻量级锁的标
记位,偏向锁标记位、分代年龄等。

Klass Pointer:Class对象的类型指针,Jdk1.8默认开启指针压缩后为4字节,关闭指针压缩( -
XX:-UseCompressedOops )后,长度为8字节。其指向的位置是对象对应的Class对象(其对应的
元数据对象)的内存地址。

对象实际数据:包括对象的所有成员变量,大小由各个成员变量决定,比如:byte占1个字节8比
特位、int占4个字节32比特位。

对齐:最后这段空间补全并非必须,仅仅为了起到占位符的作用。由于HotSpot虚拟机的内存管理
系统要求对象起始地址必须是8字节的整数倍,所以对象头正好是8字节的倍数。因此当对象实例
数据部分没有对齐的话,就需要通过对齐填充来补全。

通过ClassLayout打印对象头

为了让大家更加直观的看到对象的存储和实现,我们可以使用JOL查看对象的内存布局。

添加Jol依赖

<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>

编写测试代码,在不加锁的情况下,对象头的信息打印

public class Demo {
        Object o=new Object();
        public static void main(String[] args) {
            Demo demo=new Demo(); //o这个对象,在内存中是如何存储和布局的。
            System.out.println(ClassLayout.parseInstance(demo).toPrintable());
        }
    }

输出内容如下:

com.Demo object internals:
OFFSET SIZE TYPE DESCRIPTION
VALUE
0 4 (object header)
01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header)
00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header)
05 c1 00 f8 (00000101 11000001 00000000 11111000) (-134168315)
12 4 java.lang.Object Demo.o
(object)
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值