AtomicInteger 浅谈

AtomicInteger提供了一种线程安全的整型操作方法,利用CAS原理避免了synchronized带来的锁等待问题,有效提升了多线程环境下的应用性能。
众所周知,AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。
要使用多处理器系统的功能,通常需要使用多线程构造应用程序。但是正如任何编写并发应用程序的人可以告诉你的那样,要获得好的硬件利用率,只是简单地在多个线程中分割工作是不够的,还必须确保线程确实大部分时间都在工作,而不是在等待更多的工作,或等待锁定共享数据结构。而synchronized来控制并发就需要去等待这个锁资源,这步是非常消耗资源的,处理的吞吐量也就下去了。而java的concurrent 并发包提供的AtomicInteger就提供CAS原理避免了锁等待,具体的实现是通过UnSafe类来直接操作底层的硬件资源。
CAS是Compare And Swap的简写。意思就是比较并交换。CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。对应到AtomicInteger的源码就是
/**
* Atomically increments by one the current value.
*
* @return the previous value
*/
public final int getAndIncrement() {
for (;;) {
int current = get();//使用volatile关键字修饰AtomicInteger 的value,在每次加1前都从主存中获取最新的value值。
int next = current + 1;
if (compareAndSet(current, next))//CAS比较并交换,如果这个current 还是原来那个,即没有其他线程修改到,那么就把加1后的新值替换以前的值。
return current;
}
用个for循环,就是在有其他线程改变了这个current值后不断的重试,去拿到最新的值去加1.通过这样的方式来保证线程的安全,和使用synchronized达到一样的效果。

}
下面是对加synchronized和 AtomicInteger的简单性能比较:
开3个线程,对自增操作性1000000 * 1000次。处理时间如下:
synchronized time elapse:461198
AtomicInteger time elapse:88507。
附件中有测试的代码
【四轴飞行器】非线性三自由度四轴飞行器模拟器研究(Matlab代码实现)内容概要:本文围绕非线性三自由度四轴飞行器模拟器的研究展开,重点介绍了基于Matlab的建模与仿真方法。通过对四轴飞行器的动力学特性进行分析,构建了非线性状态空间模型,并实现了姿态与位置的动态模拟。研究涵盖了飞行器运动方程的建立、控制系统设计及数仿真验证等环节,突出非线性系统的精确建模与仿真优势,有助于深入理解飞行器在复杂工况下的行为特征。此外,文中还提到了多种配套技术如PID控制、状态估计与路径规划等,展示了Matlab在航空航天仿真中的综合应用能力。; 适合人群:具备一定自动控制理论基础和Matlab编程能力的高校学生、科研人员及从事无人机系统开发的工程技术人员,尤其适合研究生及以上层次的研究者。; 使用场景及目标:①用于四轴飞行器控制系统的设计与验证,支持算法快速原型开发;②作为教学工具帮助理解非线性动力学系统建模与仿真过程;③支撑科研项目中对飞行器姿态控制、轨迹跟踪等问题的深入研究; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注动力学建模与控制模块的实现细节,同时可延伸学习文档中提及的PID控制、状态估计等相关技术内容,以全面提升系统仿真与分析能力。
### AtomicInteger 的线程安全用法示例 `AtomicInteger` 是 Java 提供的一个用于多线程环境下的原子操作类[^1]。它通过无锁机制(基于 CAS,Compare-And-Swap)来保证线程安全,而无需显式使用 `synchronized` 关键字。以下是关于 `AtomicInteger` 的基本用法和一个线程安全的示例。 #### 基本用法 `AtomicInteger` 提供了多种原子操作方法,例如 `getAndIncrement()`、`incrementAndGet()`、`compareAndSet()` 等。这些方法确保在多线程环境下对共享变量的操作是线程安全的。 以下是一个简单的例子,展示如何使用 `AtomicInteger` 来生成唯一的序列号: ```java import java.util.concurrent.atomic.AtomicInteger; public class Sequencer { private final AtomicInteger sequenceNumber = new AtomicInteger(0); public int next() { return sequenceNumber.getAndIncrement(); // 原子性地获取并递增 } public static void main(String[] args) { Sequencer sequencer = new Sequencer(); System.out.println(sequencer.next()); // 输出 0 System.out.println(sequencer.next()); // 输出 1 System.out.println(sequencer.next()); // 输出 2 } } ``` 在这个例子中,`getAndIncrement()` 方法以原子方式返回当前并将其递增[^2]。 #### 多线程环境下的线程安全示例 为了演示 `AtomicInteger` 在多线程环境下的线程安全性,可以参考以下代码: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class AtomicIntegerExample { private final AtomicInteger counter = new AtomicInteger(0); public void incrementCounter() { counter.incrementAndGet(); // 原子性地递增计数器 } public int getCounterValue() { return counter.get(); // 获取当前 } public static void main(String[] args) throws InterruptedException { AtomicIntegerExample example = new AtomicIntegerExample(); ExecutorService executor = Executors.newFixedThreadPool(10); for (int i = 0; i < 1000; i++) { executor.submit(example::incrementCounter); } executor.shutdown(); executor.awaitTermination(1, TimeUnit.MINUTES); System.out.println("Final Counter Value: " + example.getCounterValue()); } } ``` 在这个例子中,多个线程同时调用 `incrementCounter()` 方法来递增共享的 `AtomicInteger` 变量。由于 `incrementAndGet()` 方法是原子操作,因此即使在高并发环境下,最终的结果也始终是正确的[^4]。 #### 注意事项 尽管 `AtomicInteger` 提供了线程安全的操作,但需要注意的是,仅当操作完全依赖于单个 `AtomicInteger` 实例时,才能保证线程安全。如果需要组合多个操作或与其他非原子变量交互,则可能需要额外的同步机制[^3]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值