前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >java中的Atomic类

java中的Atomic类

作者头像
程序那些事
发布于 2020-07-08 07:33:54
发布于 2020-07-08 07:33:54
63200
代码可运行
举报
文章被收录于专栏:程序那些事程序那些事
运行总次数:0
代码可运行

java中的Atomic类

问题背景

在多线程环境中,我们最常遇到的问题就是变量的值进行同步。因为变量需要在多线程中进行共享,所以我们必须需要采用一定的同步机制来进行控制。

通过之前的文章,我们知道可以采用Lock的机制,当然也包括今天我们讲的Atomic类。

下面我们从两种方式来分别介绍。

Lock

在之前的文章中,我们也讲了同步的问题,我们再回顾一下。如果定义了一个计数器如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Counter {

    int counter;

    public void increment() {
        counter++;
    }

}

如果是在单线程环境中,上面的代码没有任何问题。但是如果在多线程环境中,counter++将会得到不同的结果。

因为虽然counter++看起来是一个原子操作,但是它实际上包含了三个操作:读数据,加一,写回数据。

我们之前的文章也讲了,如何解决这个问题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class LockCounter {

    private volatile int counter;

    public synchronized void increment() {
        counter++;
    }
}

通过加synchronized,保证同一时间只会有一个线程去读写counter变量。

通过volatile,保证所有的数据直接操作的主缓存,而不使用线程缓存。

这样虽然解决了问题,但是性能可能会受影响,因为synchronized会锁住整个LockCounter实例。

使用Atomic

通过引入低级别的原子化语义命令(比如compare-and-swap (CAS)),从而能在保证效率的同时保证原子性。

一个标准的CAS包含三个操作:

  1. 将要操作的内存地址M。
  2. 现有的变量A。
  3. 新的需要存储的变量B。

CAS将会先比较A和M中存储的值是否一致,一致则表示其他线程未对该变量进行修改,则将其替换为B。否则不做任何操作。

使用CAS可以不用阻塞其他的线程,但是我们需要自己处理好当更新失败的情况下的业务逻辑处理情况。

Java提供了很多Atomic类,最常用的包括AtomicInteger, AtomicLong, AtomicBoolean, 和 AtomicReference.

其中的主要方法:

  1. get() – 直接中主内存中读取变量的值,类似于volatile变量。
  2. set() – 将变量写回主内存。类似于volatile变量。
  3. lazySet() – 延迟写回主内存。一种常用的情景是将引用重置为null的情况。
  4. compareAndSet() – 执行CAS操作,成功返回true,失败返回false。
  5. weakCompareAndSet() – 比较弱的CAS操作,不同的是它不执行happens-before操作,从而不保证能够读取到其他变量最新的值。

我们看下怎么用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class AtomicCounter {

    private final AtomicInteger counter = new AtomicInteger(0);

    public int getValue() {
        return counter.get();
    }
    public void increment() {
        while(true) {
            int existingValue = getValue();
            int newValue = existingValue + 1;
            if(counter.compareAndSet(existingValue, newValue)) {
                return;
            }
        }
    }
}

本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/atomic

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序那些事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
AtomicInteger 核心源码解析
原子类使用 CAS 替代锁,实现基本类似,我们本文以 AtomicInteger 为例来研究其究竟是如何实现无锁同步的.
JavaEdge
2020/05/26
4560
volatile关键字原理的使用介绍和底层原理解析和使用实例
volatile 关键字常用在 DCL(Double Check Lock)单例模式中:
青山师
2023/05/05
3000
AtomicInteger 核心源码解析
原子类使用 CAS 替代锁,实现基本类似,我们本文以 AtomicInteger 为例来研究其究竟是如何实现无锁同步的.
JavaEdge
2020/05/06
3590
AtomicInteger 核心源码解析
Java中的12个原子操作类
当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值。 比如变量 i = 1,A 线程更新 i+1,B 线程也更新i+1,经过两个线程操作之后可能 i 不等于 3,而是等于 2 。 因为 A 和 B 线程在更新变量 i 的时候拿到的 i 都是 1,这就是 线程不安全的更新操作,通常我们会使用 synchronized 来解决这个问题,synchronized 会保证多线程不会同时更新变量 i。
103style
2022/12/19
2950
理解Java轻量级并发包Atom系列工具类的设计
他们的主要功能是提供轻量级的同步能力从而帮助我们避免内存一致性错误,从源码中观察这些工具类其设计主要利用了CAS原语+volatile的功能。我们知道volatile虽然是轻量级的同步工具,但由于其不保证单个变量更新原子性,所以一直不能大展身手,现在有了CAS提供的lock-free的原子性,两者一结合便造了Atomic开头的这些轻量级的工具类。
我是攻城师
2018/08/03
6580
理解Java轻量级并发包Atom系列工具类的设计
Java中CAS算法的集中体现:Atomic原子类库,你了解吗?
在前面的博文中我们学习了volatile关键字,知道了它可以保证有序性和可见性,但无法保障原子性,结局原子性问题推荐使用synchronized、Lock或者AtomicInteger;我们还学习过CAS算法,在那篇博文中我们同样也提及atomic。那么今天,我们就来好好学一学Atomic原子库,一个基于CAS算法实现的高效并发工具库!
JavaBuild
2024/05/27
1060
Java中CAS算法的集中体现:Atomic原子类库,你了解吗?
吃透并发编程之—-Atomic原子类学习思考
发生冲突的情况会大大增加 (也就是存在大量更新时去比较预期的值发生了变化,导致此次更新失效的情况),因此效率会大大降低
Joseph_青椒
2023/09/07
2590
吃透并发编程之—-Atomic原子类学习思考
原子操作类解读
Java中提供了一些原子操作类,用于实现多线程环境下的数据同步问题。其中最常见的有以下几种:
一个风轻云淡
2023/10/15
2380
原子操作类解读
Java 多线程系列Ⅶ
JUC 是 Java 并发包(java.util.concurrent)的简称,该包在 Java 5.0 版本引入,提供了在并发编程中常用的工具类。这些工具类包括用于多线程同步的锁(如 ReentrantLock),用于线程池的 ExecutorService,用于原子操作的 AtomicInteger 等。这些类和接口都是非阻塞的,设计目标是在多线程环境下提供高性能和可扩展性。
终有救赎
2024/02/27
1750
并发编程-04线程安全性之原子性Atomic包的4种类型详解
并发编程-06线程安全性之可见性 (synchronized + volatile)
小小工匠
2021/08/17
3260
JUC 包中的 Atomic 原子类总结
Atomic 翻译成中文是“原子”的意思。在化学上,原子是构成物质的最小单位,在化学反应中不可分割。在编程中,Atomic 指的是一个操作具有原子性,即该操作不可分割、不可中断。即使在多个线程同时执行时,该操作要么全部执行完成,要么不执行,不会被其他线程看到部分完成的状态。
人不走空
2024/07/19
900
JUC 包中的 Atomic 原子类总结
Java中的Atomic包使用指南
Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下,无锁的进行原子操作。原子变量的底层使用了处理器提供的原子指令,但是不同的CPU架构可能提供的原子指令不一样,也有可能需要某种形式的内部锁,所以该方法不能绝对保证线程不被阻塞。
用户1212940
2022/04/13
6170
Java并发编程(2)- 线程安全性详解
说到原子性,就不得不提及JDK里的atomic包,该包中提供了很多Atomic的类,本小节主要介绍该包中常用的几个类。这些类都是通过CAS来实现原子性的,atomic包提供了如下具有原子性的类:
端碗吹水
2020/09/23
3360
Java并发编程(2)- 线程安全性详解
了解 Java 中的 AtomicInteger 类
在多线程编程中,保证数据的原子性操作是至关重要的。而 Java 提供了一系列的原子类来支持这一需求,其中之一就是 AtomicInteger。它是 Java.util.concurrent.atomic 包下的一个类,主要用于对整型变量进行原子操作。
人不走空
2024/02/24
1290
详述 Java 并发编程中 CAS 以及 AQS 的实现原理
CAS(Compare And Swap),即比较并交换,是解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS 操作包含三个操作数——内存位置V、预期原值A和新值B。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值;否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。
CG国斌
2020/06/10
8420
一篇搞定CAS,深度讲解,面试实践必备
在高并发的业务场景下,线程安全问题是必须考虑的,在JDK5之前,可以通过synchronized或Lock来保证同步,从而达到线程安全的目的。但synchronized或Lock方案属于互斥锁的方案,比较重量级,加锁、释放锁都会引起性能损耗问题。
程序新视界
2022/07/29
4000
一篇搞定CAS,深度讲解,面试实践必备
jdk-Atomic源码学习
atomic是并发框架中的一员,所属位置:java.util.concurrent.atomic 该类主要是用来解决内存可见性、有序、线程安全,当然底层也是通过cas来实现,所以性能相同步锁也是高不少。
逍遥壮士
2023/02/28
3400
jdk-Atomic源码学习
AtomicInteger详解
因为在阻塞队列中LinkedBlockingQueue中对容量的维护使用了Atomic类,所以需要对该类学习下,如何使用AtomicInteger来保证线程操作的原子性。
虞大大
2020/08/26
1K0
Atomic 原子类
Atomic 翻译成中文是原子的意思。在化学中,原子是构成一般物质的最小单位,是不可分割的。而在这里,Atomic 表示当前操作是不可中断的,即使是在多线程环境下执行,Atomic 类,是具有原子操作特征的类。
happyJared
2019/07/10
1.1K0
Atomic 原子类
Java原子操作Atomic类详解
      1.CAS(Compare And Swap,比较并交换),通常指的是这样一种原子操作:
忧愁的chafry
2022/10/30
7290
Java原子操作Atomic类详解
相关推荐
AtomicInteger 核心源码解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文