ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

秋招之路8:JAVA锁体系和AQS抽象队列同步器

2020-02-20 21:56:31  阅读:264  来源: 互联网

标签:状态 同步 JAVA AQS CAS 线程 自旋 秋招


整个的体系图

悲观锁,乐观锁

是一个广义概念;体现的是看待线程同步的不同角度。

悲观锁

认为在自己使用数据的时候一定有别的线程来修改数据,在获取数据的时候会先加锁,确保数据不被别的线程修改。
实现:关键字synchronized,接口Lock的实现类
适用场景:写操作多,先加锁可以保证写操作时的数据正确。

乐观锁

认为自己在使用数据的时候不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。
实现:CAS算法,例如AtomicInteger类的原子自增是通过CAS自旋实现
适用场景:读操作比较多,不加锁的特点能使读操作性能大幅提升。

悲观锁,乐观锁的执行流程

CAS算法

全名:Compare And Swap
也叫无锁算法:基于硬件原语实现,在不使用锁(没有线程被阻塞)的情况下,实现多线程之间的变量同步。
jdk中实现:java.util.concurrent包中的原子类(AtomicInteger)就是通过CAS来实现了乐观锁。

实现原理

算法设计的三个操作数
需要读写的内存值V
进行比较的值(版本)A
要写入的新值B

流程如下:
如果内存位置的值V与预期原值A相匹配,那么处理器会自动将该位置值更新为新值B;
否则,不要更改该位置,只告诉我这个位置现在的值,只告诉我这个位置现在的值即可(具体//)。
具体图为:

基于CAS实现的原子类关键方法

AtomicInteger.getAndDecrementUnsafe.getAndAddInt
源码:稍后补

CAS存在问题

ABA问题

因为CAS需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,
但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化过。

ABA问题的解决思路就是使用版本号。
在变量前面追加上版本号,每次变量更新的时候把版本号加一,那么A-B-A 就会变成1A-2B-3A。

循环开销时间长

只能保证一个共享变量的原子操作

从Java1.5开始JDK提供了AtomicReference类来保证引用对象之间的原子性,
可以把多个变量放在一个对象里来进行CAS操作。

自旋锁

它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。

但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。

线程的上下文切换

一个重要的问题:线程切换为什么会耗资源耗时间?

  1. 线程切换的时候,CPU需要将此线程的所有执行状态保存起来,如线程编号,执行到的位置等,然后再去执行其它线程。
  2. CPU运行状态分为用户态和内核态。线程切换状态会使CPU运行状态从用户态转换到内核态。
    这里面有一篇:专门讲用户态和内存态的[https://www.cnblogs.com/maxigang/p/9041080.html]。

AQS队列同步器原理


ReentrantLock中的一个内部类

其具体是基于CLH队列实现。

具体原理

AQS 是构建锁或者其他同步组件的基础框架(如 ReentrantLock、ReentrantReadWriteLock、Semaphore 等), 包含了实现同步器的细节(获取同步状态、FIFO 同步队列)。AQS 的主要使用方式是继承,子类通过继承同步器,并实现它的抽象方法来管理同步状态。

  1. 维护一个同步状态 state。当 state > 0时,表示已经获取了锁;当state = 0 时,表示释放了锁。
  2. AQS 通过内置的 FIFO 同步队列来完成资源获取线程的排队工作:如果当前线程获取同步状态失败(锁)时,AQS 则会将当前线程以及等待状态等信息构造成一个节点(Node)并将其加入同步队列,同时会阻塞当前线程当同步状态释放时,则会把节点中的线程唤醒,使其再次尝试获取同步状态。

AQS 内部维护的是** CLH 双向同步队列**

具体原理图

标签:状态,同步,JAVA,AQS,CAS,线程,自旋,秋招
来源: https://www.cnblogs.com/whyaza/p/12336777.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有