【JUC基础】10. Atomic原子类

news/2024/11/25 3:04:29/

1、什么是Atomic

Atomic英译为原子的。原子结构通常称为不可分割的最小单位。而在JUC中,java.util.concurrent.atomic 包是 Java 并发库中的一个包,提供了原子操作的支持。它包含了一些原子类,用于在多线程环境下进行线程安全的原子操作。使用原子类可以避免使用锁和同步机制,从而减少了线程竞争和死锁的风险,并提高了多线程程序的性能和可伸缩性。

2、为什么要使用Atomic

这里是JUC专栏,肯定是跟多线程有关系的。我们实现这样一个场景:2个线程对某个数值+1操作,每个线程累加10000次。

2.1、传统模式

package atomic;import java.util.concurrent.atomic.AtomicInteger;/*** @author Shamee loop* @date 2023/5/22*/
public class AtomicTest {private static int counter = 0;public static void main(String[] args) {// 多个线程并发地增加计数器的值Thread thread1 = new Thread(() -> {for (int i = 0; i < 10000; i++) {counter++;}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 10000; i++) {counter++;}});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println("Counter value: " + counter);}
}

执行结果:

不管运行多少次,每次的结果都不一样,而且最终的值大概率都不会是20000。而20000才是我们期望的输出。

2.2、原子模式

package atomic;import java.util.concurrent.atomic.AtomicInteger;/*** @author Shamee loop* @date 2023/5/22*/
public class AtomicTest {// 原子性intprivate static AtomicInteger counter = new AtomicInteger(0);public static void main(String[] args) {// 多个线程并发地增加计数器的值Thread thread1 = new Thread(() -> {for (int i = 0; i < 10000; i++) {// 等同于++操作counter.incrementAndGet();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 10000; i++) {counter.incrementAndGet();}});thread1.start();thread2.start();thread1.join();thread2.join();System.out.println("Counter value: " + counter.get());}
}

运行结果:

不管运行多少次,结果都是20000。可以看出代码中不需要加任何锁,Atomic在多线程场合天然的具备线程安全。

3、原子类

java.util.concurrent.atomic包下常用的原子类分为:

3.1、原子基本类型

  • AtomicInteger:整形原子类
  • AtomicLong:长整型原子类
  • AtomicBoolean :布尔型原子类

3.2、原子引用类型

  • AtomicReference:引用类型原子类

3.3、原子数组类

  • AtomicIntegerArray:整形数组原子类
  • AtomicLongArray:长整形数组原子类
  • AtomicReferenceArray :引用类型数组原子类

......

4、原子类是绝对线程安全吗?

首先,什么是线程安全问题?

在多线程编程中,线程安全是指多个线程同时访问一个共享资源时,不会产生不正确的结果或破坏数据结构的属性。

其实Atomic的原子性是指属性的存取(get/set)方法是线程安全,他的线程安全保证并不是简单的使用synchronized或lock锁。而是使用了乐观锁CAS(Compare And Swap,比较并交换)+volatile。关于CAS,可以参考《简单理解CAS》。正如CAS锁的ABA问题,它并不能保证对象是线程安全的。

因此Atomic并不是绝对的线程安全。

在多线程编程中,"atomic"操作通常被认为是一种细粒度的同步机制,用于保护共享数据的访问和修改。它们通常比其他同步机制(如锁)的开销更小,并且可以提供一定程度的线程安全性。

"atomic"操作的行为因编程语言和上下文而异,以下是一些常见情况和注意事项:

  1. 原子读取(Atomic Reads):"atomic"操作可以确保从共享变量中读取的值是最新的。这意味着一个线程在读取共享变量时,不会看到另一个线程修改变量后的旧值。
  2. 原子写入(Atomic Writes):"atomic"操作可以确保将值写入共享变量时的原子性。这意味着一个线程在写入共享变量时,不会被其他线程的读取或写入操作中断或干扰。
  3. 原子递增和递减(Atomic Increment/Decrement):某些编程语言提供原子递增和递减操作,以确保对共享计数器的操作是线程安全的。这些操作会在执行过程中阻止其他线程的干扰。

尽管"atomic"操作提供了一定的线程安全性,但在处理复杂的并发场景时,仍然需要考虑其他因素,如数据竞争、同步机制的选择和使用正确的内存模型等。此外,"atomic"操作并不能解决所有的线程安全问题,如死锁、竞争条件等。

因此,如果在特定的编程语言或框架中使用"atomic"操作,建议查阅相关文档和规范,以了解其具体行为和适用范围。同时,仍然需要谨慎设计和编写多线程代码,以确保整个程序的线程安全性。


http://www.ppmy.cn/news/85492.html

相关文章

程序的运行和发布

1. 什么是程序 经过上一章的描述应该知道编程是怎么来的&#xff0c;但是程序的内容是什么应该还没有清楚的认识。 简单来说&#xff0c;程序就是数据和代码的组合。 所谓的数据&#xff0c;就是代码操作的对象&#xff0c;数字可以看成是数据&#xff0c;文本可以看成是数据&…

【Linux0.11代码分析】09 之 ELF可执行程序02 - Section Headers解析

【Linux0.11代码分析】09 之 ELF可执行程序02 - Section Headers解析 一、ELF概述二、ELF的组成结构2.1 ELF header&#xff1a;解析出 section headers 含31个section节和 program headers 含13个segment段2.2 Section Headers&#xff1a;获取当前程序的31个section节区信息2…

【算法设计与分析】理论 实验考核回顾

写在前面&#xff1a; 1&#xff1a;本文所有内容均为只作为参考&#xff0c;当年考题不可能重复近三年考过的内容。实验部分完整更新&#xff08;因为可以自己带电脑且开卷考试&#xff09;&#xff0c;理论部分只更新记忆中的大题。 2&#xff1a;本人真的是一个算法菜鸡&a…

基于3.0.0-cdh6.3.2版本编译Flink1.14.4

一、背景 异常描述 CDH-6.3.2环境下使用Flink-1.14.4的FlinkSQL的hive方言时出现如下异常 java.lang.Runtimelxception: java,lang.IllegalArgumentException: Unrecoonized Hadoop major version number: 3.0.0-cdh6.2.1 问题说明 开源社区hive 2.x的版本这种情况下是不支…

ChatGPT Plus 是否值得购买?

ChatGPT Plus 是什么? ChatGPT Plus 是 OpenAI 推出的高级版人工智能语言模型&#xff0c;相比普通版 ChatGPT&#xff0c;它拥有更多的参数、更大的模型规模和更强大的性能。ChatGPT Plus 的训练数据覆盖了更广泛的领域和语言&#xff0c;可以生成更准确、更流畅的语言输出&…

位图和布隆过滤器

目录 位图 布隆过滤器 位图 假设有1000 万个范围在1~ 1亿的整数。如何快速查找某个整数是否出现在这1000万个整数中? 当然&#xff0c;这个问题仍然可以使用哈希表来解决。不过&#xff0c;针对这个“特殊”问题&#xff0c;我们可以使用一种比较“特殊”的哈希表&#xff…

Apache Doris

1.Doris 简介 1.1 Doris 概述 Apache Doris 由百度大数据部研发&#xff08;之前叫百度 Palo&#xff0c;2018 年贡献到 Apache 社区后&#xff0c; 更名为 Doris &#xff09;&#xff0c;在百度内部&#xff0c;有超过 200 个产品线在使用&#xff0c;部署机器超过 1000 台&a…

screen使用方法

"screen" 是一个在 Linux 和 Unix 系统中的终端多路复用工具&#xff0c;它允许你在单个终端窗口中创建多个会话&#xff0c;并在这些会话之间切换。使用 "screen" 可以在一个终端窗口中同时运行多个命令行程序&#xff0c;或者在断开连接后仍然保持程序运…