写点什么

java 多线程——CAS

作者:StackOverflow
  • 2022 年 9 月 29 日
    湖北
  • 本文字数:979 字

    阅读完需:约 3 分钟

java多线程——CAS

公平锁 vs 非公平锁

假设三个线程 A, B, C. A 先尝试获取锁, 获取成功. 然后 B 再尝试获取锁, 获取失败, 阻塞等待; 然后 C 也尝试获取锁, C 也获取失败, 也阻塞等待.

当线程 A 释放锁的时候, 会发生啥呢?

公平锁: 遵守 “先来后到”. B 比 C 先来的. 当 A 释放锁的之后, B 就能先于 C 获取到锁.非公平锁: 不遵守 “先来后到”. B 和 C 都有可能获取到锁.

操作系统内部的线程调度就可以视为是随机的. 如果不做任何额外的限制, 锁就是非公平锁. 如果要想实现公平锁, 就需要依赖额外的数据结构, 来记录线程们的先后顺序.

公平锁和非公平锁没有好坏之分, 关键还是看适用场景.synchronized 是非公平锁.

可重入锁 vs 不可重入锁

可重入锁的字面意思是“可以重新进入的锁”,即允许同一个线程多次获取同一把锁

什么是 CAS

CAS: 全称 Compare and swap,字面意思:”比较并交换“,一个 CAS 涉及到以下操作:

CAS 伪代码

boolean CAS(address, expectValue, swapValue) { if (&address == expectedValue) {   &address = swapValue;        return true;   }    return false; }
复制代码

当多个线程同时对某个资源进行 CAS 操作,只能有一个线程操作成功,但是并不会阻塞其他线程,其他线程只会收到操作失败的信号。

CAS 可以视为是一种乐观锁. (或者可以理解成 CAS 是乐观锁的一种实现方式)

CAS 是怎么实现的

java 的 CAS 利用的的是 unsafe 这个类提供的 CAS 操作;unsafe 的 CAS 依赖了的是 jvm 针对不同的操作系统实现的 Atomic::cmpxchg;Atomic::cmpxchg 的实现使用了汇编的 CAS 操作,并使用 cpu 硬件提供的 lock 机制保证其原子性。

简而言之,是因为硬件予以了支持,软件层面才能做到。

实现原子类

标准库中提供了 java.util.concurrent.atomic 包, 里面的类都是基于这种方式来实现的.典型的就是 AtomicInteger 类. 其中的 getAndIncrement 相当于 i++ 操作.

AtomicInteger atomicInteger = new AtomicInteger(0);// 相当于 i++atomicInteger.getAndIncrement();
复制代码


伪代码实现:

class AtomicInteger {    private int value;    public int getAndIncrement() {        int oldValue = value;        while ( CAS(value, oldValue, oldValue+1) != true) {            oldValue = value;       }        return oldValue;   }}
通过形如上述代码就可以实现一个原子类. 不需要使用重量级锁, 就可以高效的完成多线程的自增操作.
复制代码


发布于: 刚刚阅读数: 3
用户头像

StackOverflow

关注

天道酬勤 2022.07.01 加入

csdn java领域优质创作者 InfoQ签约作者 擅长领域:Java 算法

评论

发布
暂无评论
java多线程——CAS_编程_StackOverflow_InfoQ写作社区