原子类是Java中提供的一种用于实现线程安全操作的类。这些类通过利用底层硬件的原子操作(Atomic Operations),实现了高效的线程安全。这些类主要位于java.util.concurrent.atomic
包中,提供了一些基本类型(如整数、布尔、引用)的原子操作,以及数组和对象字段的原子操作。
常用的原子类
Java 提供了多种原子类,主要包括以下几类:
- AtomicInteger:
AtomicInteger
提供了对int
类型的原子操作。- AtomicLong:
AtomicLong
提供了对long
类型的原子操作。- AtomicBoolean:
AtomicBoolean
提供了对boolean
类型的原子操作。- AtomicReference:
AtomicReference
提供了对对象引用的原子操作。- AtomicStampedReference:
AtomicStampedReference
提供了带有版本戳的对象引用的原子操作,常用于解决 ABA 问题。- AtomicIntegerArray:提供对整数数组元素的原子操作。
- AtomicLongArray:提供对长整数数组元素的原子操作。
- AtomicReferenceArray:提供对对象数组元素的原子操作。
1. AtomicInteger 示例
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample {
private static AtomicInteger atomicInt = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
atomicInt.incrementAndGet();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
atomicInt.incrementAndGet();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final value: " + atomicInt.get());
}
}
运行结果
Final value: 2000
2. AtomicLong 示例
import java.util.concurrent.atomic.AtomicLong;
public class AtomicLongExample {
private static AtomicLong atomicLong = new AtomicLong(0);
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
atomicLong.incrementAndGet();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
atomicLong.incrementAndGet();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final value: " + atomicLong.get());
}
}
运行结果
Final value: 2000
3. AtomicBoolean 示例
import java.util.concurrent.atomic.AtomicBoolean;
public class AtomicBooleanExample {
private static AtomicBoolean atomicBoolean = new AtomicBoolean(false);
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
while (!atomicBoolean.get()) {
// busy-waiting
}
System.out.println("Thread 1 detected change to true");
});
Thread t2 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
atomicBoolean.set(true);
System.out.println("Thread 2 set value to true");
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
运行结果
Thread 2 set value to true
Thread 1 detected change to true
4. AtomicReference 示例
import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceExample {
private static AtomicReference<String> atomicReference = new AtomicReference<>("initial value");
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
atomicReference.set("Thread 1 value");
});
Thread t2 = new Thread(() -> {
atomicReference.set("Thread 2 value");
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final value: " + atomicReference.get());
}
}
运行结果
Final value: Thread 2 value
5. AtomicStampedReference 示例
import java.util.concurrent.atomic.AtomicStampedReference;
public class AtomicStampedReferenceExample {
private static AtomicStampedReference<String> atomicStampedReference =
new AtomicStampedReference<>("initial value", 0);
public static void main(String[] args) throws InterruptedException {
int[] stampHolder = new int[1];
String initialValue = atomicStampedReference.get(stampHolder);
Thread t1 = new Thread(() -> {
int stamp = atomicStampedReference.getStamp();
atomicStampedReference.compareAndSet(initialValue, "Thread 1 value", stamp, stamp + 1);
});
Thread t2 = new Thread(() -> {
int stamp = atomicStampedReference.getStamp();
atomicStampedReference.compareAndSet(initialValue, "Thread 2 value", stamp, stamp + 1);
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Final value: " + atomicStampedReference.getReference());
System.out.println("Final stamp: " + atomicStampedReference.getStamp());
}
}
运行结果
Final value: Thread 2 value
Final stamp: 1
总结
这些示例代码演示了如何使用 Java 原子类进行线程安全的操作。运行结果显示了在多线程环境中,原子类能够保证操作的原子性和线程安全性。需要注意的是,在不同的运行环境中,由于线程调度的不确定性,具体的输出顺序可能会有所不同,但最终的结果应该是一致的,符合预期。