跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
原子类应用
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= 原子类应用 = 原子类(Atomic Classes)是Java并发编程中提供的一组线程安全工具,用于在不使用锁的情况下实现'''原子性操作'''。它们通过硬件级别的'''CAS(Compare-And-Swap)'''指令实现高效的无锁并发控制。 == 核心原理 == 原子类的实现基于以下两个关键机制: * '''volatile变量''':保证内存可见性 * '''CAS操作''':通过{{code|Unsafe}}类调用CPU原子指令 <mermaid> flowchart LR A[线程A读取值] --> B[CAS尝试修改] C[线程B读取值] --> D[CAS尝试修改] B -->|成功| E[更新值] D -->|失败| F[重试操作] </mermaid> == 主要原子类 == Java提供多种原子类,可分为四类: === 基本类型 === * {{code|AtomicBoolean}} * {{code|AtomicInteger}} * {{code|AtomicLong}} === 数组类型 === * {{code|AtomicIntegerArray}} * {{code|AtomicLongArray}} * {{code|AtomicReferenceArray}} === 引用类型 === * {{code|AtomicReference}} * {{code|AtomicStampedReference}}(解决ABA问题) * {{code|AtomicMarkableReference}} === 字段更新器 === * {{code|AtomicIntegerFieldUpdater}} * {{code|AtomicLongFieldUpdater}} * {{code|AtomicReferenceFieldUpdater}} == 代码示例 == === 计数器实现 === <syntaxhighlight lang="java"> import java.util.concurrent.atomic.AtomicInteger; public class AtomicCounter { private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); // 原子性+1操作 } public int getCount() { return count.get(); } public static void main(String[] args) throws InterruptedException { AtomicCounter counter = new AtomicCounter(); // 创建100个线程并发增加计数器 Thread[] threads = new Thread[100]; for (int i = 0; i < 100; i++) { threads[i] = new Thread(() -> { for (int j = 0; j < 1000; j++) { counter.increment(); } }); threads[i].start(); } // 等待所有线程完成 for (Thread t : threads) { t.join(); } System.out.println("Final count: " + counter.getCount()); // 输出: Final count: 100000 } } </syntaxhighlight> === 复杂CAS操作 === <syntaxhighlight lang="java"> AtomicInteger atomicInt = new AtomicInteger(100); // 只有当当前值为100时才更新为200 boolean success = atomicInt.compareAndSet(100, 200); System.out.println("Update success: " + success + ", new value: " + atomicInt.get()); // 尝试更新失败示例 success = atomicInt.compareAndSet(100, 300); System.out.println("Update success: " + success + ", current value: " + atomicInt.get()); /* 输出: Update success: true, new value: 200 Update success: false, current value: 200 */ </syntaxhighlight> == 性能对比 == 下表展示不同实现方式的性能差异(单位:纳秒/操作): {| class="wikitable" |- ! 实现方式 !! 10线程 !! 100线程 |- | synchronized || 120 || 950 |- | ReentrantLock || 85 || 620 |- | AtomicInteger || 15 || 130 |} == 实际应用场景 == === 场景1:全局唯一ID生成 === <syntaxhighlight lang="java"> class IdGenerator { private AtomicLong id = new AtomicLong(0); public long nextId() { return id.getAndIncrement(); } } </syntaxhighlight> === 场景2:状态标志控制 === <syntaxhighlight lang="java"> class TaskRunner { private AtomicBoolean running = new AtomicBoolean(false); public void start() { if (running.compareAndSet(false, true)) { // 启动任务 } } public void stop() { running.set(false); } } </syntaxhighlight> === 场景3:高效统计 === <syntaxhighlight lang="java"> class Statistics { private AtomicIntegerArray hourCounts = new AtomicIntegerArray(24); public void record(int hour) { hourCounts.getAndIncrement(hour % 24); } } </syntaxhighlight> == 高级特性 == === 原子累加器 === Java 8引入更高效的{{code|LongAdder}}和{{code|DoubleAdder}},适用于高并发统计场景: <syntaxhighlight lang="java"> import java.util.concurrent.atomic.LongAdder; LongAdder adder = new LongAdder(); // 多线程并发调用 adder.add(5); adder.increment(); System.out.println(adder.sum()); // 获取当前总和 </syntaxhighlight> === 原子引用更新 === 解决ABA问题的{{code|AtomicStampedReference}}示例: <syntaxhighlight lang="java"> AtomicStampedReference<String> ref = new AtomicStampedReference<>("A", 0); int[] stampHolder = new int[1]; String current = ref.get(stampHolder); // 同时获取值和版本戳 // 只有当值和版本戳都匹配时才更新 ref.compareAndSet(current, "B", stampHolder[0], stampHolder[0]+1); </syntaxhighlight> == 数学原理 == CAS操作的数学表示为: <math> CAS(V, E, N) = \begin{cases} V = N & \text{如果 } V == E \\ \text{无操作} & \text{其他情况} \end{cases} </math> 其中: * V = 内存中的变量值 * E = 预期值 * N = 新值 == 最佳实践 == * 优先使用原子类替代synchronized * 对于简单操作(如计数器)使用基本原子类 * 高并发统计场景使用{{code|LongAdder}} * 引用类型更新注意ABA问题 * 避免过度依赖{{code|getAndSet}},可能丢失中间状态 {{Warning|原子类不保证多个操作的原子性,复合操作仍需外部同步}} [[Category:计算机科学]] [[Category:面试技巧]] [[Category:Java并发编程]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)