为了避免显示使用synchronized和Lock,在某些场景我们会用cas来避免以上两者的性能开销,cas也叫做原子操作,底层通过计算机底层的cmpxchg指令来实现,cmpxchg介绍如下
cmpxchg 指令的基本格式如下:
assemblycmpxchg destination, source
其中:
destination 是目标操作数,通常是一个内存地址或寄存器。source 是源操作数,通常是一个寄存器。cmpxchg 指令的工作原理如下:
destination 中的值与累加器(通常是 AL、AX 或 EAX 寄存器,具体取决于操作数的大小)中的值进行比较。destination 中的值等于累加器中的值,则将 source 中的值写入 destination。ZF 标志位)。以下是一个简单的示例,展示如何在汇编语言中使用 cmpxchg 指令:
assemblysection .data value db 5 section .text global _start _start: mov al, 5 ; 将累加器 AL 设置为 5 mov bl, 10 ; 将寄存器 BL 设置为 10 lock cmpxchg [value], bl ; 比较并交换 ; 检查 ZF 标志位来判断操作是否成功 jz success jmp failure success: ; 操作成功 ; 在这里添加成功处理代码 jmp exit failure: ; 操作失败 ; 在这里添加失败处理代码 jmp exit exit: ; 退出程序 mov eax, 60 ; syscall: exit xor edi, edi ; status: 0 syscall
在这个示例中:
value 是一个内存地址,存储了一个字节值 5。al 寄存器被设置为 5,bl 寄存器被设置为 10。lock cmpxchg [value], bl 指令将 value 中的值与 al 中的值进行比较,如果相等,则将 bl 中的值 10 写入 value。ZF 标志位的状态,程序会跳转到 success 或 failure 标签进行相应的处理。cmpxchg 指令在多线程编程中非常有用,特别是在实现无锁数据结构时。Java 中的 AtomicInteger 类就是基于 CAS 操作实现的,而 CAS 操作通常使用 cmpxchg 指令来实现。
javaimport java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerExample {
private static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) {
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
counter.incrementAndGet();
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final counter value: " + counter.get());
}
}
现总结一下他的常用方法
AtomicInteger():创建一个初始值为 0 的 AtomicInteger 实例。
AtomicInteger(int initialValue):创建一个初始值为 initialValue 的 AtomicInteger 实例。
int get():获取当前值。
void set(int newValue):设置新值。
int getAndSet(int newValue):获取当前值并设置新值。
int getAndIncrement():获取当前值并自增 1。
int getAndDecrement():获取当前值并自减 1。
int getAndAdd(int delta):获取当前值并加上 delta。
int incrementAndGet():自增 1 并返回新值。
int decrementAndGet():自减 1 并返回新值。
int addAndGet(int delta):加上 delta 并返回新值。
这些已经够用了
在 AtomicInteger类源码中,我们可以看到
java /*
* This class intended to be implemented using VarHandles, but there
* are unresolved cyclic startup dependencies.
*/
private static final Unsafe U = Unsafe.getUnsafe();
public final int incrementAndGet() {
return U.getAndAddInt(this, VALUE, 1) + 1;
}
....
追溯到Unsafe类
java // 自旋操作
@IntrinsicCandidate
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
v = getIntVolatile(o, offset);
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
return v;
}
@IntrinsicCandidate
public final boolean weakCompareAndSetInt(Object o, long offset,
int expected,
int x) {
return compareAndSetInt(o, offset, expected, x);
}
@IntrinsicCandidate
public final native boolean compareAndSetInt(Object o, long offset,
int expected,
int x);
追溯到这里,后面就是native方法,由cpp实现,使用,除了AtomicInteger,Java还有很多其他的相似类

下面讲解一下他们的用法,先是AtomicBoolean
以下是 AtomicBoolean 类中一些常用的方法:
构造方法:
AtomicBoolean():创建一个初始值为 false 的 AtomicBoolean 实例。AtomicBoolean(boolean initialValue):创建一个初始值为 initialValue 的 AtomicBoolean 实例。获取和设置值:
boolean get():获取当前值。void set(boolean newValue):设置新值。boolean getAndSet(boolean newValue):获取当前值并设置新值。CAS 操作:
boolean compareAndSet(boolean expect, boolean update):如果当前值等于 expect,则将其更新为 update,并返回 true;否则返回 false。javapackage com.reservoir;
import java.util.concurrent.atomic.AtomicBoolean;
public class AtomicBooleanExample {
private static AtomicBoolean flag = new AtomicBoolean(false);
public static void main(String[] args) {
// 创建多个线程并发地修改 flag 的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
Boolean b = flag.get();
flag.getAndSet(!b);
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的 flag 值
System.out.println("Final flag value: " + flag.get());
}
}
AtomicBoolean使用了Java9的VarHandle机制
接下来是AtomicIntegerArray ,提供对整数数组进行原子操作的功能。
构造方法:
AtomicIntegerArray(int length):创建一个给定长度的 AtomicIntegerArray 实例,所有元素初始值为 0。AtomicIntegerArray(int[] array):创建一个 AtomicIntegerArray 实例,元素值从给定的数组中复制。获取和设置值:
int get(int i):获取索引 i 处的当前值。void set(int i, int newValue):设置索引 i 处的新值。int getAndSet(int i, int newValue):获取索引 i 处的当前值并设置新值。原子更新操作:
int getAndIncrement(int i):获取索引 i 处的当前值并自增 1。int getAndDecrement(int i):获取索引 i 处的当前值并自减 1。int getAndAdd(int i, int delta):获取索引 i 处的当前值并加上 delta。int incrementAndGet(int i):自增 1 并返回索引 i 处的新值。int decrementAndGet(int i):自减 1 并返回索引 i 处的新值。int addAndGet(int i, int delta):加上 delta 并返回索引 i 处的新值。javaimport java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayExample {
private static AtomicIntegerArray array = new AtomicIntegerArray(10);
public static void main(String[] args) {
// 创建多个线程并发地增加数组元素的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < array.length(); j++) {
array.incrementAndGet(j);
}
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的数组值
for (int i = 0; i < array.length(); i++) {
System.out.println("Array element at index " + i + ": " + array.get(i));
}
}
}
接下来是AtomicIntegerFieldUpdater 用于提供对指定类的指定 volatile int 字段进行原子操作的功能。
以下是 AtomicIntegerFieldUpdater 类中一些常用的方法:
创建 AtomicIntegerFieldUpdater:
static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName):创建一个 AtomicIntegerFieldUpdater 实例,用于更新指定类的指定 volatile int 字段。获取和设置值:
int get(T obj):获取指定对象的指定字段的当前值。void set(T obj, int newValue):设置指定对象的指定字段的新值。int getAndSet(T obj, int newValue):获取指定对象的指定字段的当前值并设置新值。原子更新操作:
int getAndIncrement(T obj):获取指定对象的指定字段的当前值并自增 1。int getAndDecrement(T obj):获取指定对象的指定字段的当前值并自减 1。int getAndAdd(T obj, int delta):获取指定对象的指定字段的当前值并加上 delta。int incrementAndGet(T obj):自增 1 并返回指定对象的指定字段的新值。int decrementAndGet(T obj):自减 1 并返回指定对象的指定字段的新值。int addAndGet(T obj, int delta):加上 delta 并返回指定对象的指定字段的新值。javaimport java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public class AtomicIntegerFieldUpdaterExample {
private static class Counter {
volatile int count;
}
private static final AtomicIntegerFieldUpdater<Counter> updater =
AtomicIntegerFieldUpdater.newUpdater(Counter.class, "count");
public static void main(String[] args) {
Counter counter = new Counter();
// 创建多个线程并发地增加 count 的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
updater.incrementAndGet(counter);
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的 count 值
System.out.println("Final count value: " + counter.count);
}
}
接下来讲解Long相关的原子操作类它们分别是 AtomicLong、AtomicLongArray、AtomicLongFieldUpdater 和 LongAdder。
AtomicLong 是 Java 并发包中的一个类,用于提供对 long 类型进行原子操作的功能。它通过无锁算法(基于 CAS 操作)来实现线程安全的原子操作。
构造方法:
AtomicLong():创建一个初始值为 0 的 AtomicLong 实例。AtomicLong(long initialValue):创建一个初始值为 initialValue 的 AtomicLong 实例。获取和设置值:
long get():获取当前值。void set(long newValue):设置新值。long getAndSet(long newValue):获取当前值并设置新值。原子更新操作:
long getAndIncrement():获取当前值并自增 1。long getAndDecrement():获取当前值并自减 1。long getAndAdd(long delta):获取当前值并加上 delta。long incrementAndGet():自增 1 并返回新值。long decrementAndGet():自减 1 并返回新值。long addAndGet(long delta):加上 delta 并返回新值。javaimport java.util.concurrent.atomic.AtomicLong;
public class AtomicLongExample {
private static AtomicLong counter = new AtomicLong(0);
public static void main(String[] args) {
// 创建多个线程并发地增加 counter 的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
counter.incrementAndGet();
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的 counter 值
System.out.println("Final counter value: " + counter.get());
}
}
用于提供对 long 数组进行原子操作的功能。
构造方法:
AtomicLongArray(int length):创建一个给定长度的 AtomicLongArray 实例,所有元素初始值为 0。AtomicLongArray(long[] array):创建一个 AtomicLongArray 实例,元素值从给定的数组中复制。获取和设置值:
long get(int i):获取索引 i 处的当前值。void set(int i, long newValue):设置索引 i 处的新值。long getAndSet(int i, long newValue):获取索引 i 处的当前值并设置新值。原子更新操作:
long getAndIncrement(int i):获取索引 i 处的当前值并自增 1。long getAndDecrement(int i):获取索引 i 处的当前值并自减 1。long getAndAdd(int i, long delta):获取索引 i 处的当前值并加上 delta。long incrementAndGet(int i):自增 1 并返回索引 i 处的新值。long decrementAndGet(int i):自减 1 并返回索引 i 处的新值。long addAndGet(int i, long delta):加上 delta 并返回索引 i 处的新值。javaimport java.util.concurrent.atomic.AtomicLongArray;
public class AtomicLongArrayExample {
private static AtomicLongArray array = new AtomicLongArray(10);
public static void main(String[] args) {
// 创建多个线程并发地增加数组元素的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < array.length(); j++) {
array.incrementAndGet(j);
}
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的数组值
for (int i = 0; i < array.length(); i++) {
System.out.println("Array element at index " + i + ": " + array.get(i));
}
}
}
AtomicLongFieldUpdater 用于提供对指定类的指定 volatile long 字段进行原子操作的功能。
创建 AtomicLongFieldUpdater:
static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName):创建一个 AtomicLongFieldUpdater 实例,用于更新指定类的指定 volatile long 字段。获取和设置值:
long get(T obj):获取指定对象的指定字段的当前值。void set(T obj, long newValue):设置指定对象的指定字段的新值。long getAndSet(T obj, long newValue):获取指定对象的指定字段的当前值并设置新值。原子更新操作:
long getAndIncrement(T obj):获取指定对象的指定字段的当前值并自增 1。long getAndDecrement(T obj):获取指定对象的指定字段的当前值并自减 1。long getAndAdd(T obj, long delta):获取指定对象的指定字段的当前值并加上 delta。long incrementAndGet(T obj):自增 1 并返回指定对象的指定字段的新值。long decrementAndGet(T obj):自减 1 并返回指定对象的指定字段的新值。long addAndGet(T obj, long delta):加上 delta 并返回指定对象的指定字段的新值。javaimport java.util.concurrent.atomic.AtomicLongFieldUpdater;
public class AtomicLongFieldUpdaterExample {
private static class Counter {
volatile long count;
}
private static final AtomicLongFieldUpdater<Counter> updater =
AtomicLongFieldUpdater.newUpdater(Counter.class, "count");
public static void main(String[] args) {
Counter counter = new Counter();
// 创建多个线程并发地增加 count 的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
updater.incrementAndGet(counter);
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的 count 值
System.out.println("Final count value: " + counter.count);
}
}
LongAdder 用于提供对 long 类型进行累加操作的功能,特别适用于高并发场景下的累加操作。基于分段锁
构造方法:
LongAdder():创建一个 LongAdder 实例。累加操作:
void add(long x):将指定的值 x 累加到当前值。void increment():将当前值自增 1。void decrement():将当前值自减 1。获取值:
long sum():返回当前的总和。void reset():重置总和为 0。long sumThenReset():返回当前的总和,并重置总和为 0。javaimport java.util.concurrent.atomic.LongAdder;
public class LongAdderExample {
private static LongAdder counter = new LongAdder();
public static void main(String[] args) {
// 创建多个线程并发地增加 counter 的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的 counter 值
System.out.println("Final counter value: " + counter.sum());
}
}
接下来是引用相关的操作类,有三个与引用类型相关的类,它们分别是 AtomicReference、AtomicReferenceArray 和 AtomicReferenceFieldUpdater。
AtomicReference 是 Java 并发包中的一个类,用于提供对引用类型进行原子操作的功能。
构造方法:
AtomicReference():创建一个 AtomicReference 实例,初始值为 null。AtomicReference(V initialValue):创建一个 AtomicReference 实例,初始值为 initialValue。获取和设置值:
V get():获取当前值。void set(V newValue):设置新值。V getAndSet(V newValue):获取当前值并设置新值。javaimport java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceExample {
private static AtomicReference<String> atomicString = new AtomicReference<>("initial");
public static void main(String[] args) {
// 创建多个线程并发地修改 atomicString 的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
String oldValue;
String newValue;
do {
oldValue = atomicString.get();
newValue = oldValue + i;
} while (!atomicString.compareAndSet(oldValue, newValue));
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的 atomicString 值
System.out.println("Final atomicString value: " + atomicString.get());
}
}
AtomicReferenceArray 是 Java 并发包中的一个类,用于提供对引用类型数组进行原子操作的功能。
构造方法:
AtomicReferenceArray(int length):创建一个给定长度的 AtomicReferenceArray 实例,所有元素初始值为 null。AtomicReferenceArray(E[] array):创建一个 AtomicReferenceArray 实例,元素值从给定的数组中复制。获取和设置值:
E get(int i):获取索引 i 处的当前值。void set(int i, E newValue):设置索引 i 处的新值。E getAndSet(int i, E newValue):获取索引 i 处的当前值并设置新值。javaimport java.util.concurrent.atomic.AtomicReferenceArray;
public class AtomicReferenceArrayExample {
private static AtomicReferenceArray<String> array = new AtomicReferenceArray<>(10);
public static void main(String[] args) {
// 初始化数组
for (int i = 0; i < array.length(); i++) {
array.set(i, "initial");
}
// 创建多个线程并发地修改数组元素的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < array.length(); j++) {
String oldValue;
String newValue;
do {
oldValue = array.get(j);
newValue = oldValue + i;
} while (!array.compareAndSet(j, oldValue, newValue));
}
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的数组值
for (int i = 0; i < array.length(); i++) {
System.out.println("Array element at index " + i + ": " + array.get(i));
}
}
}
AtomicReferenceFieldUpdater 是 Java 并发包中的一个类,用于提供对指定类的指定 volatile 引用字段进行原子操作的功能。
创建 AtomicReferenceFieldUpdater:
static <U, W> AtomicReferenceFieldUpdater<U, W> newUpdater(Class<U> tclass, Class<W> vclass, String fieldName):创建一个 AtomicReferenceFieldUpdater 实例,用于更新指定类的指定 volatile 引用字段。获取和设置值:
V get(T obj):获取指定对象的指定字段的当前值。void set(T obj, V newValue):设置指定对象的指定字段的新值。V getAndSet(T obj, V newValue):获取指定对象的指定字段的当前值并设置新值。javaimport java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public class AtomicReferenceFieldUpdaterExample {
private static class Container {
volatile String value;
}
private static final AtomicReferenceFieldUpdater<Container, String> updater =
AtomicReferenceFieldUpdater.newUpdater(Container.class, String.class, "value");
public static void main(String[] args) {
Container container = new Container();
container.value = "initial";
// 创建多个线程并发地修改 container 的 value 字段的值
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
String oldValue;
String newValue;
do {
oldValue = updater.get(container);
newValue = oldValue + i;
} while (!updater.compareAndSet(container, oldValue, newValue));
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终的 value 值
System.out.println("Final value: " + container.value);
}
}
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!