[转帖]synchronizedlock和cas理解

Posted jinanxiaolaohu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[转帖]synchronizedlock和cas理解相关的知识,希望对你有一定的参考价值。

synchronized、lock和cas理解

https://blog.csdn.net/qq_41908272/article/details/94736856

 

这是小编我在看完ReentrantLock类之后对这几种可以实现锁的方式的理解,如果有什么理解的不对的,大家可以一起交流,共同进步。

synchronized
synchronized这个关键子是java语言中可以用于实现锁的一种方式。这个关键字我们一般称为同步。这种加锁的方式也是我们平常经常用到的,就比如说小编前段时间碰到的一个问题,用户领取优惠券,这时发现一个用户在领取优惠券时都会发生多领的情况,不用考虑,直接加锁,这是可以不费吹灰之力就可以解决问题的方式。但是加在哪里,怎么加这是很有可能会影响到系统的运行速度。现在先来看下synchronized可以加在哪几个地方,并说一下加在这些地方会对什么东西上锁。

//1??
synchronized (this){

}
//2??
public synchronized void tset(){

}
//3??
synchronized (类名.class){

}

 



在上面的代码块中,这是synchronized可以加在这几个地方,加在不同的地方锁住的对象也是不同的,就比如说1和3,就是锁住当前进入这个方法的实例,即是锁住对象,2就是锁住这个方法,只要进入到这个方法就会被上锁。这两种锁的粒度是不同的,对象锁的粒度是较细的,方法锁的粒度较粗。当然,知道这些平常工作是够用了的,但是我们应该针对不同的应用环境来选择不同的锁,这才是我们应该了解到的。

synchronized锁的种类
synchronized锁的种类有偏向锁,轻量级锁,重量级锁,锁的状态被存储在对象头(Mark Word)中,线程会根据获取到的对象头的信息来判断锁的状态。

对象锁的升级过程
线程获取到对象头中存储锁状态的信息时,如果是无锁的状态,会判断是否支持偏向锁,支持的话会升级为偏向锁,不支持的话直接成为轻量级锁。在升级为偏向锁的过程中通过cas来替换线程,成功替换的话升级为偏向锁,失败的话退出此次锁的竞争。下面贴出从无锁升级为偏向锁或者轻量级锁的过程的图片:


偏向锁/轻量级锁升级为重量级锁一般是因为线程要释放锁时,等待的线程在进行cas竞争时,失败的次数过多,锁才会升级为重量级锁,下面贴出cas竞争的图片:


lock锁
通过lock加锁,需要实现ReentrantLock类的实例。在了解lock加锁的方式之前,肯定要先了解ReentrantLock这个类,ReentrantLock实现了Lock接口,所以ReentrantLock会实现Lock接口的一些方法,但是ReentrantLock的核心是Sync这个内部类。在这里不再细说ReentrantLock这个类,咱们继续回到锁这上面。

ReentrantLock实现的lock锁会产生两种锁,即公平锁和非公平锁。非公平锁是其默认的实现方式。这些看源码都是可以了解到的。所谓的公平锁和非公平锁就是线程在获取锁时需不需要继续等待的区别。公平锁是当一个线程释放了锁后,等待在这个线程后面的线程会获取到锁,而非公平锁是当一个线程释放锁后,新进来的线程也是可能获取到锁的。

lock锁是可重入锁,相信这些上网一查都可以查到,但是他为什么是可重入锁,这些都需要自己看源码来交接,这里小编就只是稍稍说一下,大家可以自己看下源码或者看下我的这篇文章———《》

lock锁上面已经知道需要实现ReentrantLock类的实例,也说了ReentrantLock类的核心是Sync这个内部类,这个内部类继承了AbstractQueuedSynchronizer类,也可以被称为AQS类,AQS类使用一个Node数组来存储当线程获取到锁之后正在等待的锁,并为每个正在等待线程赋予一个状态。

cas
Cas也是可以锁的,通过cas实现锁是一种思想,这种思想小编也是通过观看源码然后所熟知。通过cas来实现线程的竞争,需要volatile这个关键字来配合的使用,以此来实现锁。

在cas中既然说到了volatile这个关键字,小编在这里就在唠叨一会[捂脸]。

volatile这个关键子的作用是修饰类的全局变量的,当一个变量被它修饰时,这个变量的值就会变成当这个值发生变化时会立即通知给所有的线程,被这个变量值修饰的变量是禁止指令重排序的。volatile这个关键字是可以当被修饰的变量值发生变化时可以立即通知给所有的线程,那么如果来实现在多线程下的运算呢?小编在这里可以给出答案,在多线程的环境下,对被volatile修饰的变量进行计算时,仍然是不安全的,因为运算操作不是原子性的。
————————————————
版权声明:本文为CSDN博主「曾经的随性」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41908272/article/details/94736856

以上是关于[转帖]synchronizedlock和cas理解的主要内容,如果未能解决你的问题,请参考以下文章

synchronized 底层如何实现?啥是锁的升级,降级

java多线程---synchronizedLock

synchronizedLock接口Condition接口读写锁及ReentrantLock(重入锁) 特性及使用

[转帖]使用 smartmontools 查看硬盘的健康状态

[转帖]ORA-00600-[kcratr_nab_less_than_odr]问题小记

CAS源码追踪系列二:AuthenticationFilter对于请求的处理