面试题答案
一键面试使用AtomicInteger实现对整数的原子操作示例
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample {
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(0);
// 原子地将当前值加1
int incrementedValue = atomicInteger.incrementAndGet();
System.out.println("Incremented value: " + incrementedValue);
// 原子地将当前值减1
int decrementedValue = atomicInteger.decrementAndGet();
System.out.println("Decremented value: " + decrementedValue);
// 原子地设置新值并返回旧值
int oldValue = atomicInteger.getAndSet(10);
System.out.println("Old value: " + oldValue + ", New value: " + atomicInteger.get());
// 原子地更新值
int updatedValue = atomicInteger.updateAndGet(i -> i * 2);
System.out.println("Updated value: " + updatedValue);
}
}
Atomic类实现原子操作的原理
Atomic类实现原子操作主要依赖于硬件层面的原子指令(如CPU的CAS指令,Compare And Swap)以及Java的Unsafe类。
- CAS指令:CAS是一种硬件原语,它在一个CPU时钟周期内完成比较和交换操作。其操作需要三个操作数:内存位置(V)、预期原值(A)和新值(B)。当且仅当内存位置V的值与预期原值A相等时,处理器才会自动将内存位置V的值更新为新值B,否则处理器不做任何操作。这一过程是原子的,不会被其他线程干扰。
- Unsafe类:Java的
sun.misc.Unsafe
类提供了直接访问底层内存和硬件的能力。Atomic类通过Unsafe
类的方法来实现对特定内存位置的原子操作。例如,AtomicInteger
中的incrementAndGet
方法,实际上是通过Unsafe
类的getAndAddInt
方法实现的。getAndAddInt
方法利用CAS指令在内存中原子地更新AtomicInteger
的值。
综上所述,Atomic类利用底层硬件的原子指令和Java的Unsafe
类,保证了在多线程环境下对变量操作的原子性,避免了数据竞争和不一致问题。