[转帖]synchronized、lock和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

原文地址:https://www.cnblogs.com/jinanxiaolaohu/p/12164822.html

时间: 2024-11-07 18:34:28

[转帖]synchronized、lock和cas理解的相关文章

synchronized (lock) 买票demo 线程安全

加锁防止多个线程执行同一段代码! /** http://blog.51cto.com/wyait/1916898 * @author * @since 11/10/2018 * 某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票. * 同步的特点: * 前提: 多个线程 * 解决问题的时候要注意: 多个线程使用的是同一个锁对象 * 同步的好处:同步的出现解决了多线程的安全问题. * 同步的弊端:当线程相当多时,因为每个线程都会去判断同步上的锁,这

[转帖]synchronized、volatile、Lock详解

synchronized.volatile.Lock详解 https://blog.csdn.net/u012102104/article/details/79231159   在Java并发编程过程中,我们难免会遇到synchronized.volatile和lock,其中lock是一个类,而其余两个则是Java关键字.以下记录了小博开发过程中对这三者的理解,不足之处请多指教. 关于线程与进程请参考博文 以操作系统的角度述说线程与进程 synchronized  synchronized是Ja

从 synchronized www2015338com到 CAS 和 19908836661AQS

Java 中的并发锁大致分为隐式锁和显式锁两种.隐式锁就是我们最常使用的 synchronized 关键字,显式锁主要包含两个接口:Lock 和 ReadWriteLock,主要实现类分别为 ReentrantLock 和 ReentrantReadWriteLock,这两个类都是基于 AQS(AbstractQueuedSynchronizer) 实现的.还有的地方将 CAS 也称为一种锁,在包括 AQS 在内的很多并发相关类中,CAS 都扮演了很重要的角色.我们只需要弄清楚 synchron

Synchronized&Lock&AQS详解

加锁目的:由于线程执行的过程是不可控的,所以需要采用同步机制来协同对对象可变状态的访问. 加锁方式:java锁分为两种--显示锁和隐示锁,本质区别在于显示锁需要的是程序员自己手动的进行加锁与解锁如ReentrantLock需要进行lock与unlock.而隐式锁则是Synchronized,jvm内置锁,jvm进行操作加锁与解锁. Synchronized关键字 每个对象创建后都会存在一个Monitor(监视器锁),它的实现依赖底层的系统的Mutex Lock(互斥锁)实现,是重量级锁,但是在j

【转载】Java中的锁机制 synchronized & Lock

参考文章: http://blog.csdn.net/chen77716/article/details/6618779 目前在Java中存在两种锁机制:synchronized和Lock,Lock接口及其实现类是JDK5增加的内容,其作者是大名鼎鼎的并发专家Doug Lea.本文并不比较synchronized与Lock孰优孰劣,只是介绍二者的实现原理. 数据同步需要依赖锁,那锁的同步又依赖谁?synchronized给出的答案是在软件层面依赖JVM,而Lock给出的方案是在硬件层面依赖特殊的

Java 线程锁机制 -Synchronized Lock 互斥锁 读写锁

synchronized 是互斥锁: lock 更广泛,包含了读写锁 读写锁特点: 1)多个读者可以同时进行读2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者) 互斥锁特点: 一次只能一个线程拥有互斥锁,其他线程只有等待 所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5之前, 我们通常使用synchronized机制控制多个线程对共享资源的访问. 而现在, Lock提供了比synchronize

Synchronized && Lock

想要详细学习synchronized的同学们可以看 http://www.cnblogs.com/noKing/p/9190673.html 本文参考:  http://www.cnblogs.com/dolphin0520/p/3923167.html https://blog.csdn.net/u012403290/article/details/64910926?locationNum=11&fps=1 介绍一下Lock接口 在java.util.concurrent.locks包中,有三

[转帖]linux中systemctl详细理解及常用命令

linux中systemctl详细理解及常用命令 2019年06月28日 16:16:52 思维的深度 阅读数 30 https://blog.csdn.net/skh2015java/article/details/94012643 一.systemctl理解 Linux 服务管理两种方式service和systemctl systemd是Linux系统最新的初始化系统(init),作用是提高系统的启动速度,尽可能启动较少的进程,尽可能更多进程并发启动. systemd对应的进程管理命令是sy

java CAS理解

CAS,Compare and Swap即比较并替换,设计并发算法时常用到的一种技术.CAS有三个操作数:内存值V.旧的预期值A.要修改的值B,当且仅当预期值A和内存值V相同时,将内存值修改为B并返回true,否则什么都不做并返回false. CAS 算法大致原理是:在对变量进行计算之前(如 ++ 操作),首先读取原变量值,称为 旧的预期值 A,然后在更新之前再获取当前内存中的值,称为 当前内存值 V,如果 A==V 则说明变量从未被其他线程修改过,此时将会写入新值 B,如果 A!=V 则说明变