synchronized内部的工作原理

一、synchronized的策略

synchronized内部优化的非常好,大部分情况下使用 synchronized 不会有什么问题.

1. 乐观锁/悲观锁  自适应

2. 轻量级锁/重量级锁   自适应

3. 自旋锁/挂起等待所   自适应

4. 不是读写锁

5. 非公平锁

6. 可重入锁

二、synchronized背后的优化手段

synchronized加锁过程,尤其是 " 自适应 " 是怎么一回事呢?

synchronized在执行的时候,如果当前对象处于未加锁状态,就会经历以下过程 :

1. 偏向锁  阶段      (   假设没有其他线程和他竞争   )

核心思想 " 懒汉模式 ",能不加锁就不加锁,加锁能晚一点是一点.

所谓的偏向锁,并非是真的加锁了,而是做了一个非常轻的标记.

非必要不加锁

在遇到竞争的时候,偏向锁没有提高效率.

但如果在没有遇到竞争的情况下,偏向锁就大幅度的提高了效率.

总的来说,偏向锁的意义还是很大的.

2. 轻量级锁   阶段   (   假设有竞争但是不多   )

轻量级锁   是通过自旋锁的方式来实现的.

优势 : 别的线程释放锁,就会第一时间拿到锁

劣势 : 消耗CPU     (   如果线程比较多,都在自旋,就会消耗CPU   )

synchronized内部会统计当前这个锁对象上,有多少个线程在竞争,当发现竞争的线程比较多,就会升级为重量级锁.

3. 重量级锁   阶段

此时拿不到锁的线程就不会继续自旋了,而是进入 " 阻塞等待 " ,就不会消耗那么多的CPU,不会使CPU的占用率太高了.

当当前线程释放锁的时候,系统会随机唤醒一个线程来进行获取锁.

锁只能升级,不能降级.

4. 锁消除

锁消除,也是synchronized中内置的优化策略.

编译器优化的一种方式,编译器编译代码的时候,如果发现这个代码,不需要加锁,就会自动把锁给干掉.

比如,就只有一个线程,在这一个线程里,加锁了,

锁消除.针对一眼看上去就知道完全不涉及线程安全问题的代码,能够把锁消除掉.

偏向锁,运行起来才知道有没有锁冲突.

5. 锁粗化

会把多个细粒度的锁,合并成一个粗粒度的锁.

  ps : 

synchronized的  "{}"  中包含的代码越少,就认为锁的粒度越细,包含的代码越多,就认为锁的粒度越粗.

通常情况下,是更偏好于让锁的粒度细一点,更有利于多个线程的并发执行.

但有时候,希望锁的粒度粗一点也挺好.

像这样,一个线程自己在进行加锁解锁加锁解锁,就会把这几次加锁解锁合并为一个粗粒度的锁,这样可以减少几次加锁解锁,提高效率.

6. 小结

synchronized 背后设计到了很多的 " 优化手段"

1. 锁升级.偏向锁, -> 轻量级锁 -> 重量级锁

2. 锁消除.自动干掉不必要的锁

3. 锁粗化.把多个细粒度的锁合并为一个粗粒度的锁,减少锁竞争的开销.

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值