ReentrantLock(AQS内部结构以及加锁过程),Synchronized与Volatile

ps: CAS虽然叫做乐观锁,但是其底层仍然使用了锁,其基于unsafe类的方法实现,unsafe类的compareandset方法来自C++的本地方法,编译成汇编语言后在CAS操作的过程中加了一个lock指令,保证在机器码层面CPU执行的一系列指令是原子的。

一、ReentrantLock底层原理

可重入锁的内部结构,源码以及程序中是如何重复加锁的,简要总结如下图,方便以后自己回顾
请添加图片描述

补充一下AQS内部的运行机制:

主要注意的是:

  1. 双向链表首节点是一个占位的哨兵节点
  2. 通过锁的state值和哨兵节点与等待节点的waitStatus的值触发回调函数,导致节点的自旋,哨兵的挂起线程,唤醒线程等操作;
  3. 等待线程获取锁成功后原先的哨兵节点会被GC回收,原先等待的首个节点所在内存中的节点成为新的哨兵节点。

请添加图片描述

二、Synchronized底层原理

基于C语言的Monitor(操作系统中的管程)对象实现,保证可见性、有序性和原子性,Monitor对象中主要有三个关键字段:owner、EntryList、WaitSet;

owner:指向的是当前持有锁的线程;
EntryList:尝试获取锁的线程队列;
WaitSet:持有锁的线程执行wait指令后将进入该集合;

  • Sychronized作用于同步块时,编译成字节码后会在同步块前后加上monitorenter和monitorexit指令,表示该程序块为同步块,线程访问该程序块需要等待当前线程执行完该程序块才可进入;
  • Sychronized作用于方法时,该方法被编译成字节码后会有一个Access flag属性来标识该方法为同步方法,同一时刻只有一个线程可以访问;

psSychronized实现可见性Sychronized块中包含的属性字段会被从CPU私有缓存中清除,这样每次线程要取用这些变量都会强制去公有内存中读取,保证读到的都是最新值。

三、Volatile底层原理

是一个轻量级的Sychronized,只保证可见性和有序性;

  • 保证可见性:每次有线程要改变由其修饰的变量时,通过总线机制和缓存一致性机制会强行零其他CPU中含有该变量的缓存行失效,因此,其他线程会被迫去共享内存中再次读取该属性值。

  • 保证有序性:基于JVM层面的指令屏障实现,会在被其修饰的变量操作前后加上JVM规定要实现的四种指令屏障(LoadLoad、StoreStore、LoadStore、StoreLoad),从而保证前后指令不会被重排序;

底层是通过C语言实现的,在编译成汇编语言后会加上一个lock指令,由其保证上述的可见性和有序性。(一方面lock指令会使缓存行失效保证可见性,另一方面,lock指令前后所有指令都不能乱序执行)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值