3、synchronized

###实现原理
synchronized是通过指令monitorentor 和monitorexit指令实现的

synchronized实现原理
由上图可以看出,线程想要访问对象,是需要监视器(Monitor)配合同步队列(SynchronizedQueue)给对象加锁的。

SynchronizedQueue 同步队列是一个双向链表 FIFO ,也是由CAS原理实现的
为什么使用链表 而不使用数组? 是因为双向链表 可以在新增和删除的时候,各加一个锁,一共2个锁,性能更高。而数组只能加1个锁。

###锁的信息放在哪儿?

synchronized是给对象或类加的锁。

1、对于普通的同步方法,锁的是当前的对象
2、对于静态的同步方法,锁的是当前的类
3、对于同步代码块,锁的是()里的对象。

锁的信息放在对象的头部(head)的markword中

###锁的级别
在Java1.6,doug lea(李狗蛋)对synchronized做了优化

##偏向锁

偏向锁是在对象头部的mark word 中维护了一个线程ID,当该线程再次访问对象获取锁的时候,先根据这个线程ID判断是否是该线程。。

释放锁: 只有在出现锁竞争的情况下才会释放锁。释放的过程:暂停拿到锁的该线程,如果该线程已死亡,设置头部的Mark Word为无锁的状态

缺点:如果线程之间存在锁竞争,会带来额外的锁撤销的消耗。适合于只有1个线程访问同步块的场景

关闭偏向锁:可以通过JVM关闭偏向锁:-XX:-UseBiasedLocking=false;
程序会默认进入轻量级锁的状态。

##轻量级锁

轻量级锁也叫乐观锁,是通过cas原理实现的。

#什么是CAS
顾名思义:compare and swap(比较并替换)

老数据:A 期待值: B 写入:V
通过unsafe类中的JNI(Java本地方法,C++)自旋(死循环),不断的判断A 是否等于 B ,假如相等:那么写入V

释放锁:会用CAS将Mark Word的锁状态标记为无锁,如果成功,则释放。如果失败,则表示存在竞争。这时,锁就会膨胀为重量级锁

缺点:不断的自旋消耗CPU的性能

##重量级锁
为总线锁。锁的粒度大,同一时刻,只有1个CPU能访问主内存。

缺点:性能低下。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值