Synchronized

今天要说的话题是并发编程之Synchronized


说Synchronized之前,得先聊一下CAS。首先,什么是CAS呢? compare and swap。

例如,两个线程都去内存之中,取A的值,并且进行更新,每次更新的时候,先比较一下A的值和我之前拿的值是否是一样的,如果一样就更新成功,如果不一样,就把A的新值重新拿出来,然后进行下一轮CAS操作。

那么这样会引发什么问题呢?

这就是我们常说的ABA问题,怎么解决呢,可以采用乐观锁的思路,加上版本号来解决。

CAS的底层是基于什么做的呢?从上面可以看出,有两个动作,首先取出值进行比较,然后决定是否更新,这个其实是需要原子性的,也就是说,在取值比较到更新这个过程中,cpu不能够对这个内存值进行写的操作。

Lock cmpxchg,这个就是CAS的底层实现的命令,也可以提前告诉你,synchronize底层也是用这条命令实现的。


CAS已经这么好了,为什么还要加锁呢?问这个问题之前,首先要问一下自己,为什么加锁不好?

看上图,因为加锁是一个操作内存,但是jvm属于一个程序,是用户空间里面的东西,但是加锁只用内核空间里面才能干,故需要用户从用户态转化为内核态,通过内核去申请锁,需要耗费额外的性能。说一个简单的例子,你去外面玩耍,有一个公共卫生间,加锁的动作是,你不管三七二十一,先去门口的看门人,申请一把锁,然后再去上厕所。你想想如果你不去申请这把锁,直接进去看看有没有人,然后再决定下一个动作是不是快很多。

说了锁的不好的一面,再说一个CAS的不好的地方,你们想,如果CAS的参与者过多,是不是会出现大量线程在它拿到更新权利之前,都需要不断的自旋,因为每次只会有一个线程可以更新成功,其他的线程要拿到新值继续cas,所以这个过程中是十分消耗cpu资源的,倒不如直接加锁,锁没释放之前,我就阻塞在哪里,而不是一直自旋着。


再说一下,对象在内存之中是如何保存的:

上图说的是64位操作系统,markword占8个字节,klassword占8个字节(开启指针压缩占4个字节,默认是开启的),数据区就是每个对象或者数据里面的数据,对其区是为了保证总的大小为8个字节的整数倍而设定的。至于为什么要是8的倍数,因为cpu每次读取数据是64位也就是8个字节,为了保证效率才这样的。

markword:1,线程的hashcode 2,垃圾回收的信息 3,锁的信息

klassword:指向方法区class的地址值


终于到了synchronize,我们直接说jdk1.6之后的版本,因为1.6之前都是重量级锁。那就没什么好说的。

锁是有一个升级的过程的,

首先说偏向锁, 偏向锁是什么?还记得上面我们说的markword里面存着线程的hashcode值,其实偏向锁,就是用到了这个,

偏向锁其实就是在门上贴上了自己的线程id,下次访问的时候直接看一下id,是自己的 直接进去,为什么要这样设计?因为大多数业务场景中的大多数时间里面,其实不存在多线程的竞争问题,这个时候如果只有一个线程在访问,那么不管是cas还是锁都没有太大意义,所以偏向锁是为了解决这个问题的。

偏向锁,还要注意的是,我们可以设置是否开启,jvm默认的是延迟4秒开启偏向锁,为什么要延迟4S开启,因为在jvm启动的时候,有很多资源是多线程竞争的,所以即使开启了,也会立马升级为轻量级锁或者重量级锁,升级过程中,还要先撤销掉偏向锁是需要消耗性能的,延迟开始其实是一个小优化。

轻量锁, 什么是轻量锁,就是上面说的CAS 自旋的过程,那么偏向锁什么条件会升级到轻量锁,其实也很简单,只要出现两个线程在竞争,就会升级为轻量级锁,轻量锁较偏向锁不同的是,每次都去CAS操作看能不能更新门上的线程id为自己的。

重量锁,什么是重量锁,上面的说的偏向锁和轻量锁,其实不难发现,都是用户自己在自己的空间里面玩,但是重量级锁不一样,直接告诉内核,我要加把锁,也就是通过对额外的系统资源上锁,来达到串行化的效果,如果一个线程来了,发现门上已经上锁了,那么它不再自旋了,直接进入一个等待队列waitset,进行等待锁的释放。轻量锁什么时候升级为重量锁,老的jvm版本其中的一种条件是轻量锁有线程自旋10次以上的情况下,并且这个参数可以自己设置,新的jvm是自动判断什么时候是重度自旋,会自动升级。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值