synchronized的底层实现原理

简述:
什么是synchronized?sysnchronized就是同步的意思,故名思意是用来保证线程安全的。

synchronized(同步):当一个或者多个线程同时访问一个临界资源的时候,只允许有一个

线程访问,其他线程排队等候。当这个线程彻底把锁释放之后,才允许下个线程去访问

该临界资源,并且再次获取该锁,执行下面操作,直至把锁释放。下图可以清楚的展示该结

论。

在这里插入图片描述
在这里插入图片描述

图一:没有加synchronized关键字,当多个线程并发访问该资源的时候,当其中一

个线程去执行count--操作,将值减一,如果第一个线程读到它是0,然会减1,当这

个线程还没有将数据保存到自己的线程栈中,第二个线程又来将他的值又改为0,所以

结果为0。这就说明在访问临界资源的时候,他的值可能被其它线程修改。

图二:
 加了同步关键字,synchronized,也就是说多个线程并发访问该临界资源的时候,当

其中一个线程去执行count--操作的时候,读到它是0,然后进行减1,然后进行打印

当第二个线程来访问该资源的时候,首先看第一个线程是否释放该锁,释放该锁,第

二个线程获取该锁,执行操作,也就是说只允许一个线程对它操作,其它线程不允

许修改该操作。

2.介绍完概念型的东西,再来说说它的原理,它是怎么执行的,作用在哪
里?它是给对象头(markword和class pointer)上锁,锁的是对象头。
那么对象在内存中是如何布局的呢?
在这里插入图片描述
上图就清晰的展示对象在内存的的关系布局图,那么具体的这几部分都代表什么呢?一一来说下:

1. markword:存储一些存储锁的信息,有偏向锁记录,偏向时间戳,锁标志位,偏向线

   程,id,GC分代年龄,hahcode,basied_lock(锁状态)。指针记录。

2.类型指针(class pointer):类元数据指针,当我们new出来一个对象,可以根据
  
  该指针到jvm虚拟机的方法区找到对应的类。就知道对象是哪个类的实例。

3.实例数据(instance):位于虚拟机的堆区,存放实例数据。

4.对齐填充(padding):什么也不存放,由于虚拟机给默认的对象是8的倍数,当不够
   
   8的倍数,会自动填充。

介绍完对象的信息,我们并且知道synchronized上锁的地方是对象头的markword,那么jdk8中的markword的实现是怎样的呢?
在这里插入图片描述
总共记录的了4种锁状态,其中GC是垃圾回收器,当啥时候堆内存满了的时候才启用它,一般虚拟机默认不会启用。

无锁态: 在堆内存中开辟25bit的空间来存放对象的hashcode,开辟4bit的空间存

GC分代年龄。1bit空间用来判断是否偏向锁:0,2bit存放锁标志位:01。

轻量级锁:直接开辟30bit的空间来存放指向自身线程栈记录的指针,开辟2bit存放

锁标志位:00

重量级锁:开启30bit的空间来存放互斥量(重量级锁)的指针。开辟2bit存放锁标志

位:10

GC分代年龄:存放的数据为空,开辟2bit空间存放锁标识位:11

偏向锁:开辟23bit空间用来标识自身线程栈的线程ID,2bit存放偏向时间戳(epoch),

4bit存放GC分代年龄,1bit用来标识是否为偏向锁位:1,2bit来标识锁标志位。

这就是jdk8对markword的实现。那么到底是怎么上锁的呢?锁的是对象哪里呢?
在这里插入图片描述
上面就是通过jol框架打印出来的对象关系布局图,红色标记为就记录我们的锁状态和锁标志位。这就是锁的对象头。0位无锁状态。
那么synchronized是可以从以下3方面的实现:

1.源码角度: 在这里插入图片描述
这就是源码角度的对象上锁。

2.字节码层级的实现:通过monitorenter和monitorexit指令来给对象上锁和解锁,当执行monitorenter的时候给对象加锁,获取monitor对象监视器,进行以下执行操作。当执行完monitorexit释放锁。大家看下图:
在这里插入图片描述
上图我们看出从字节码层级上的synchronized的实现。

3.HotSpot的实现(可以查看openjdk的源码,直接从github官网下载):

直接奉上源码的实现:在这里插入图片描述 在这里插入图片描述

首先,说明下,在软件层面的最终实现是:lock指令 lock  cmpxchg  =cas+修改变量值

在硬件层面,lock指令在执行后面指令的时候锁定了一个北桥信号(电信号)。

在c++源码中:有一条汇编指令:asm  volatile (LOCK_IF MP(%4) "cmpxchg  %1,(%3)")

这行代码是已经接入操作系统了,volatile的底层最终实现也是该lock指令

至此,我们就把synchronized的实现原理以及在哪里上锁弄明白了,这是自己对此的了解,望对大家有帮助。后面我会给大家分享锁竞争与锁升级的过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值