您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Java多线程中原子性操作类怎么用
## 目录
1. [原子性操作类概述](#一原子性操作类概述)
2. [基本类型原子类](#二基本类型原子类)
3. [数组类型原子类](#三数组类型原子类)
4. [引用类型原子类](#四引用类型原子类)
5. [字段更新原子类](#五字段更新原子类)
6. [原子类的底层原理](#六原子类的底层原理)
7. [原子类的性能对比](#七原子类的性能对比)
8. [实际应用场景](#八实际应用场景)
9. [常见问题与解决方案](#九常见问题与解决方案)
10. [总结与最佳实践](#十总结与最佳实践)
---
## 一、原子性操作类概述
### 1.1 什么是原子性操作
原子性操作是指不可被中断的一个或一系列操作,这些操作要么全部执行成功,要么全部不执行。
### 1.2 Java中的原子类
Java从JDK 1.5开始提供了`java.util.concurrent.atomic`包,包含以下主要类别:
| 类别 | 典型类 |
|-----------------|---------------------------|
| 基本类型 | AtomicInteger, AtomicLong |
| 数组类型 | AtomicIntegerArray |
| 引用类型 | AtomicReference |
| 字段更新器 | AtomicIntegerFieldUpdater |
### 1.3 与传统同步方式的对比
```java
// 传统方式
private int counter = 0;
public synchronized void increment() {
counter++;
}
// 原子类方式
private AtomicInteger counter = new AtomicInteger(0);
public void increment() {
counter.incrementAndGet();
}
优势对比: - 性能更高(无锁或乐观锁) - 代码更简洁 - 避免死锁风险
// 初始化
AtomicInteger atomicInt = new AtomicInteger(0);
// 常用操作
atomicInt.get(); // 获取当前值
atomicInt.set(10); // 直接设置
atomicInt.compareAndSet(expect, update); // CAS操作
atomicInt.incrementAndGet(); // ++i
atomicInt.getAndIncrement(); // i++
// 线程安全的计数器
class Counter {
private AtomicInteger count = new AtomicInteger(0);
public void add() {
count.incrementAndGet();
}
public int get() {
return count.get();
}
}
// 适用于统计场景
AtomicLong counter = new AtomicLong(0);
counter.addAndGet(100); // 增加指定值
counter.accumulateAndGet(10, (x, y) -> x * y); // 函数式更新
JDK 8+推荐使用LongAdder
替代高并发写场景:
LongAdder adder = new LongAdder();
adder.increment();
long sum = adder.sum();
// 初始化长度为10的原子数组
AtomicIntegerArray array = new AtomicIntegerArray(10);
// 原子性更新
array.set(0, 100);
array.getAndAdd(0, 5); // 下标0的元素加5
// 原子性地将第i个元素更新为newValue
boolean success = array.compareAndSet(i, expect, newValue);
AtomicLongArray
AtomicReferenceArray
AtomicReference<User> userRef = new AtomicReference<>();
User newUser = new User("Alice");
userRef.set(newUser);
// CAS更新
User oldUser = userRef.get();
User updatedUser = new User("Bob");
userRef.compareAndSet(oldUser, updatedUser);
// 初始值和版本号
AtomicStampedReference<String> ref =
new AtomicStampedReference<>("init", 0);
// 更新时检查版本
int[] stampHolder = new int[1];
String current = ref.get(stampHolder);
if(ref.compareAndSet(current, "new", stampHolder[0], stampHolder[0]+1)) {
// 更新成功
}
class MyClass {
volatile int value;
}
AtomicIntegerFieldUpdater<MyClass> updater =
AtomicIntegerFieldUpdater.newUpdater(MyClass.class, "value");
MyClass obj = new MyClass();
updater.set(obj, 10);
updater.incrementAndGet(obj);
Compare-And-Swap核心伪代码:
int compare_and_swap(int* reg, int oldval, int newval) {
int old_reg_val = *reg;
if (old_reg_val == oldval)
*reg = newval;
return old_reg_val;
}
原子类底层依赖sun.misc.Unsafe
提供的CAS操作:
public final native boolean compareAndSwapInt(
Object o, long offset, int expected, int x);
现代CPU提供的原子指令:
- x86: CMPXCHG
- ARM: LDREX/STREX
JMH测试结果(ops/ms):
实现方式 | 低并发 | 高并发 |
---|---|---|
synchronized | 1,200 | 350 |
AtomicInteger | 8,500 | 6,200 |
LongAdder | 12,000 | 28,000 |
// 网站访问统计
AtomicLong pageViews = new AtomicLong(0);
void onPageVisit() {
pageViews.incrementAndGet();
}
// 服务状态管理
AtomicReference<State> state = new AtomicReference<>(State.STOPPED);
boolean start() {
return state.compareAndSet(State.STOPPED, State.RUNNING);
}
现象:值从A→B→A,CAS无法感知中间变化
解决方案:使用AtomicStampedReference
现象:高并发时CAS失败率高
解决方案:
1. 改用LongAdder
2. 减小竞争范围(分段锁)
// 线程安全的ID生成器
class IdGenerator {
private final AtomicLong counter = new AtomicLong(0);
public long nextId() {
return counter.incrementAndGet();
}
}
”`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。