网站首页 > 博客文章 正文
AtomicInteger
AtomicInteger 是对 int 类型的一个封装,提供了原子性的访问和更新操作,其原子性操作的实现是基于CAS(compare-and-swap)技术。
AtomicInteger 提供一种线程安全的加减操作接口。
- public final int get() //获取当前的值
- public final int getAndSet(int newValue)//获取当前的值,并设置新的值
- public final int getAndIncrement() //获取当前的值,并自增
- public final int getAndDecrement() //获取当前的值,并自减
- public final int getAndAdd(int delta) //获取当前的值,并加上预期的值
看看 AtomicInteger 源代码:
private volatile int value;
volatile 关键字是保证AtomicInteger 线程安全的根源。
volatile 修饰的成员变量,在每次被线程访问时,都强迫从共享内存重新读取该成员的值,而且,当成员变量值发生变化时,强迫将变化的值重新写入共享内存,这样两个不同的线程在访问同一个共享变量的值时,始终看到的是同一个值。
Java语言规范指出:为了获取最佳的运行速度,允许线程保留共享变量的副本,当这个线程进入或者离开同步代码块时,才与共享成员变量进行比对,如果有变化再更新共享成员变量。这样当多个线程同时访问一个共享变量时,可能会存在值不同步的现象。
而volatile这个值的作用就是告诉VM:对于这个成员变量不能保存它的副本,要直接与共享成员变量交互。
建议:当多个线程同时访问一个共享变量时,可以使用volatile,而当访问的变量已在synchronized代码块中时,不必使用。
缺点:使用volatile将使得VM优化失去作用,导致效率较低,所以要在必要的时候使用。
CAS(compare-and-swap)
所谓CAS,表示的是一系列操作的集合,获取当前值,进行运算,利用CAS 指令试图进行更新。
如果当前数值未变,表示没有其他线程进行并发修改,则成功更新。
否则,可能出现不同的选择,要么进行重试,要么就返回一个成功或者失败的结果。
CAS就是Compare and Swap的意思,比较并操作。
CAS有3个操作数:
- V:内存中的值。
- B:要修改为的新值。
- A:若V==A则V=B。
其实CAS的过程也是挺简单的,来一发流程图吧。
CAS简而言之就是:CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
CAS 是Java并发中所谓 lock-free 机制的基础。
CAS 也并不是没有副作用,试想,其常用的失败重试机制,隐含着一个假设,即竞争情况是短暂的。大多数应用场景下,确实大部分重试只会发生一次就获得了成功,但是总是有意外情况,所以在有需要的时候,还是要考虑限制自旋的次数,以免过度消耗CPU。
AbstractQueuedSynchronizer(AQS)
是Java 并发包中,实现各种同步结构的基础。
AQS 内部数据和方法,可以简单拆分为:
- 一个volatile 的整数成员状态,同时提供了setState() 和 getState() 方法;
- private volatile int state;
- 一个先进先出(FIFO)的等待线程队列(waiter),实现多线程间竞争和等待,是AQS 机制的核心之一;
- 各种基于 CAS 的基础操作方法,以及各种期望具体同步结构去实现的 acquire/release 方法;
利用AQS 实现一个同步结构,至少需要实现2个基本类型的方法,分别是 acquire 操作,获取资源的独占权;还有就是 release 操作,释放对某个资源的独占。
猜你喜欢
- 2024-10-16 “全栈2019”Java多线程第三十一章:如何中断锁上正在等待的线程
- 2024-10-16 阿里巴巴Java性能调优实战:深入了解Lock同步锁的优化方法
- 2024-10-16 线程池:治理线程的法宝(线程池的实现原理和实现方法)
- 2024-10-16 程序员必须要知道的ReentrantLock 及 AQS 实现原理
- 2024-10-16 synchronized 和 ReentrantLock 的实现原理是什么?它们有什么区别
- 2024-10-16 Java线程池核心(十五):工作线程Worker
- 2024-10-16 一文搞懂分布式可重入锁(分布式锁的实现方式及优缺点)
- 2024-10-16 从Java线程池的常用4种写法深入分析线程池的实现原理
- 2024-10-16 Java基础——Java多线程(Lock接口详解)
- 2024-10-16 ReentrantLock原理及详细的使用方法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)