AtomicInteger

2024-06-16 14:52
文章标签 atomicinteger

本文主要是介绍AtomicInteger,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 前言

AtomicInteger是Java中的一个原子整数类,它提供了一种在多线程环境下进行原子性操作的方法。所谓原子性操作是指不会被线程调度机制打断的操作;这些操作可以在可能被其他线程影响的情况下作为一个不可分割的整体执行。

在并发编程中,如果多个线程同时对同一个变量进行读取和写入操作,会存在竞态条件(Race Condition),导致数据不一致或错误。为了解决这种问题,Java提供了一系列的原子类,其中包括AtomicInteger。

AtomicInteger可以保证对整型变量的操作是原子性的,比如增加、减少操作。它使用了底层的CAS(Compare and Swap)操作来实现原子性。

2. 介绍CAS

AtomicInteger的实现依赖于底层的CAS(Compare-And-Swap)操作,确保其操作是原子性的。CAS是一种硬件级别的原子操作,通常由处理器直接支持,它可以在多线程环境中保证对变量的修改不会引起竞态条件。

CAS 操作

CAS 操作涉及三个值:

  1. 内存位置(V):需要读取和更新的变量。
  2. 预期值(A):当前线程认为变量应该持有的值。
  3. 新值(B):线程希望将变量的值更新为的新值。

CAS 过程如下:

  • 检查内存位置 V 的当前值是否等于预期值 A。
  • 如果相等,则将内存位置 V 的值更新为新值 B。
  • 如果不相等,则不进行任何操作并返回当前值。

这个过程是一个原子操作,不会被其他线程中断。

AtomicInteger 实现原理

在 Java 中,AtomicInteger 类使用 CAS 操作来实现其方法。以下是它的一些关键方法及其实现原理:

incrementAndGet()

这是 AtomicInteger 类中一个常用方法,用于以原子方式将当前值加 1,并返回加 1 后的值。

public final int incrementAndGet() {for (;;) {int current = get();int next = current + 1;if (compareAndSet(current, next))return next;}
}

解释:

  1. 获取当前值:调用 get() 方法获取当前值。
  2. 计算下一个值:将当前值加 1,得到下一个值。
  3. CAS 操作:调用 compareAndSet(current, next) 尝试将当前值更新为下一个值。
    • 如果当前值等于预期值(current),则更新成功,返回更新后的值。
    • 如果当前值不等于预期值,则表示在这段时间内已经有其他线程修改了当前值。因此,循环重试,直到更新成功。
compareAndSet(int expect, int update)

这是一个本地方法(native),通常由 JVM 底层通过硬件指令实现。

public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}

解释:

  1. unsafe:使用了 Unsafe 类,这是一个提供底层操作的类。Unsafe 类允许进行低级别的、不受限制的内存操作。
  2. compareAndSwapInt:这是一个本地方法,使用底层的硬件指令来执行 CAS 操作。

为什么 AtomicInteger 是原子的

由上述实现原理可以看出,AtomicInteger 的操作是原子的,原因主要有以下几点:

  1. CAS 操作:底层的 CAS 操作保证了整个比较和交换步骤的原子性。
  2. 硬件支持:现代处理器通常提供对 CAS 操作的原生支持,这样可以确保这些操作在硬件级别上是原子的。
  3. 循环重试:如果 CAS 操作失败(因为其他线程修改了值),AtomicInteger 会自动进行循环重试,直到操作成功。

因此,AtomicInteger 能够在多线程环境中安全地进行整数操作,避免传统锁机制带来的性能损耗,同时确保操作的正确性。

这篇关于AtomicInteger的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1066748

相关文章

并发编程——按顺序打印(AtomicInteger类)

AtomicInteger类: 高并发的情况下,i++无法保证原子性,往往会出现问题,所以引入AtomicInteger类。并发编程中的原子性问题 AtomicInteger类工具方法: private static AtomicInteger atomicInteger = new AtomicInteger();// 获取当前值public static void getCurrent

并发读源码——AtomicInteger/AtomicLong/AtomicStampedReference

文章目录 1. AtomicInteger描述2. 源码解析3. AtomicInteger演示示例4. 多线程用法 1. AtomicInteger描述 AtomicInteger从名字上看是操作Integer整数的,但Integer是线程不安全的,AtomicInteger是线程安全的。AtomicInteger的作用可以把两个Integer对象的加减乘除等操作变成一个原子操

深入解析Java AtomicInteger 原子类型

Java开发中不可避免的会遇到并发的问题。在进行并发编程的时候我们需要确保程序在被多个线程并发访问时可以得到正确的结果,也就是要实现线程安全。 那么什么样的标准可以称为线程安全呢?这里有线程安全的定义: 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么这个类就是线程安全的。 举一

AtomicInteger的并发处理

转载自:http://hittyt.iteye.com/blog/1130990 JDK1.5之后的java.util.concurrent.atomic包里,多了一批原子处理类。主要用于在高并发环境下的高效程序处理。 网上关于这个原理介绍的比较靠谱的一片文章是出自IBM工程师的一篇: 流行的原子   值得一看。 这里,我们来看看AtomicInteger是

Code Fragment-使用AtomicInteger作为线程安全的程序计数器

在java中,数据的操作是非原子性的,++i 对应多条java指令。而java提供了AtomicInteger作为线程安全的数据类,在程序计数器的地方很有作用。 private static final ThreadFactory sThreadFactory = new ThreadFactory() {private final AtomicInteger id = new Atom

关于AtomicInteger的实现原理

首先给出一个并发编程时,对于计数器进行累加时有问题的程序: public class CountExample1 {// 请求总数public static int clientTotal = 5000;// 同时并发执行的线程数public static int threadTotal = 200;public static int count = 0;public static void

AtomicInteger源码解析

Java并发编程里不得不提java提供的高并发工具包,JUC包提供丰富的并发编程工具类,因此学习Java并发编程,JUC包就是学习的基础。在学习JUC包之前,我们先了解一下JUC的基本功能模块. JUC并发包的基本结构体系   atomic包:基于CAS策略的的原子类包。   locks包:是基于AQS的抽象队列的同步框架,提供并发编程的同步锁。   并发容器:提供高并发条件下的数据存储。

AtomicInteger原理

文章目录 AtomicInteger原理原理介绍源码分析 AtomicInteger原理 原理介绍 AtomicInteger的本质:自旋锁 + CAS算法 自旋锁:当一个线程在获取锁时,如果锁已经被其他线程获取,当前线程就会不断循环检查锁是否被释放,直到获取到锁 CAS的全成是: Compare And Swap(比较再交换); 是现代CPU广泛支持的一种对内存中的共享

Java多线程之原子性 volatile、atomicInteger、synchronized测试

Java自增操作不是原子性操作,有三步:读,增,写; AtomicInteger:一个提供原子操作的Integer的类。 一种线程安全的加减操作接口, 相比 synchroized、lock 高效. synchroized:可以保证多线程下原子操作,不过效率低; volatile:关键字,只能保证可见性,无法保证对变量的任何操作都是原子性的。 public class Incremen

AtomicInteger和volatile

AtomicInteger中的方法线程安全,它拥有一个volatile修饰的int类型的value值,我们通过AtoicInteger对象对value进行操作是线程安全的,以getAndIncrement()方法为例说明它是如何实现的,我们先看下源码 public final int getAndIncrement() {return unsafe.getAndAddInt(this, valu