Atomic是一个Java中的工具类,用于执行原子操作(Atomic Operations)。具体而言,它提供了一套原子性的操作方法,能够确保特定的操作在多线程环境下是原子的,即不会被其他线程中断或同时执行。

Atomic类提供了以下常用的原子操作类:

  1. AtomicBoolean:用于原子性操作布尔类型数据。
  2. AtomicInteger:用于原子性操作整型数据。
  3. AtomicLong:用于原子性操作长整型数据。
  4. AtomicReference:用于原子性操作引用类型数据。

这些类提供了一系列的原子操作方法,例如 get() 获取值,set() 设置新值,getAndSet() 先获取当前的值然后设置新值等。这些方法使用底层的硬件原语(如 CAS,Compare-And-Swap)来实现线程安全的操作。

使用Atomic类可以避免竞态条件和数据不一致的问题,因为它们能够确保操作的原子性和可见性。有了原子操作,我们可以在无需加锁的情况下对共享变量进行安全的读取和更新。

AtomicInteger的使用和说明_AtomicInteger

我们需要AtomicInteger情况:作为多个线程同时使用的原子计数器比较和交换操作中实现非阻塞算法。

AtomicInteger介绍:

AtomicInteger是Java中的一个原子整型类,它提供了一种线程安全的方式来进行原子操作,特别是针对整数类型的操作。

在多线程环境下,当多个线程同时访问和修改共享的整数变量时,可能会出现竞态条件(race condition)和数据不一致的问题。AtomicInteger通过使用底层的CAS(Compare and Swap)操作和内存屏障等技术,可以确保这些操作是原子的,从而避免了数据不一致的风险。

AtomicInteger类提供了一系列的原子操作方法,包括:

  • get():获取当前的整数值。
  • set(int newValue):设置新的整数值。
  • getAndSet(int newValue):先获取当前整数值,然后设置新的整数值。
  • incrementAndGet():自增并获取递增后的值。
  • decrementAndGet():自减并获取递减后的值。
  • getAndIncrement():先获取当前整数值,然后再自增。
  • getAndDecrement():先获取当前整数值,然后再自减。
  • addAndGet(int delta):增加指定的增量并获取结果。
  • getAndAdd(int delta):先获取当前整数值,然后增加指定的增量。

除了上述方法之外,AtomicInteger还具有一些其他的方法,用于比较和更新操作,例如compareAndSet(int expect, int update)方法可以比较当前值与期望值,如果相等则设置新值。

使用AtomicInteger可以确保对共享整数变量的操作是原子的,并且不需要显式地加锁来保护操作。这使得代码更简洁、高效,并且能够避免潜在的并发问题。

AtomicInteger的使用小举例:

import java.util.concurrent.atomic.AtomicInteger;
public class AtomicDemo {
    private static AtomicInteger counter = new AtomicInteger(0);
    public static void main(String[] args) {
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    counter.incrementAndGet();//原基础上加一
                }
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    counter.incrementAndGet(); //原基础上加一
                }
            }
        });
        thread1.start();
        thread2.start();
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("计数值: " + counter.get());
    }
}