当前位置:网站首页>AtomicInteger原子操作类
AtomicInteger原子操作类
2022-06-11 07:00:00 【一定会去到彩虹海的麦当】
️个人网站:code宝藏 ,欢迎访问
我的公众号:code宝藏 ,分享自己的学习资源,欢迎关注
非常感谢大家的支持与点赞
原子性
即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。
int++ 并不是一个原子操作,所以当一个线程读取它的值并加 1 时,另外一个线程有可能会修改原来的int值,这就会引发错误。
原子类
java.util.concurrent 这个包里面提供了一组原子类。其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,然后由 JVM 从等待队列中选择一个线程进入,这只是一种逻辑上的理解。
原子类:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
原子数组:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
原子属性更新器:AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
解决 ABA 问题的原子类:AtomicMarkableReference(通过引入一个 boolean 来反映中间有没有变过),AtomicStampedReference(通过引入一个 int 来累加来反映中间有没有变过)
AtomicInteger 原理
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex); }
}
private volatile int value;
}
AtomicInteger 类主要利用 CAS (compare and swap) + volatile 和 native 方法来保证原子操作,从而避免 synchronized 的高开销,执行效率大为提升。
CAS 的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值。
UnSafe 类的 objectFieldOffset() 方法是一个本地方法,这个方法是用来拿到 value属性的内存地址,返回值是 valueOffset,我们可以通过这个valueOffset访问value属性。
另外 value 是一个 volatile 变量,在内存中可见,因此 JVM 可以保证任何时刻任何线程总能拿到该变量的最新值。
Unsafe 对象提供了非常底层的,操作内存、线程的方法,Unsafe 对象不能直接调用,只能通过反射获得。jdk8直接调用
Unsafe.getUnsafe()获得的unsafe。
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
//unsafe.getAndAddInt
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
//获取共享变量旧值
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
compareAndSwapInt()包含三个操作数:
内存位置(var2)、预期原值(var5)和新值( var5 + var4)
如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则会自旋直到成功。
边栏推荐
- JVM from getting started to giving up 2: garbage collection
- sql查询问题,只显示列名 不显示数据
- 河南高考VS天津高考(2008年-2021年)
- Explain the difference between void 0 and undefined
- Quick sorting of graphic array [with source code]
- Starting from scratch (IV) enemy aircraft flying out of the border disappear automatically
- Use of qscriptengine class
- The difference between TCP and UDP
- Unity 全景漫游过程中使用AWSD控制镜头移动,EQ控制镜头升降,鼠标右键控制镜头旋转。
- The meaning and research significance of mathematical methodology
猜你喜欢

Latex various arrows / arrows with text labels / variable length arrows

JVM from getting started to giving up 2: garbage collection

socket. IO cross domain stepping pit

Flat design, blog website (VIII) code source code

Do you know what the quotation for it talent assignment service is? It is recommended that programmers also understand

网狐游戏服务器房间配置向导服务定制功能页实现

Flutter 约束容器组件

Web API、DOM
![JS implementation of graphic merging and sorting process [source code attached]](/img/c8/210ddab791eb2319519496f7c7d010.jpg)
JS implementation of graphic merging and sorting process [source code attached]

Object. Specific implementation and difference between create() and new
随机推荐
Saltstack deployment LNMP
Pytest自动化测试-简易入门教程(01)
572. subtree of another tree
Leetcode hot topic 100 topic 21-25 solution
你知道IT人才外派服务报价是怎样的么?建议程序员也了解下
双周投融报:资本抢滩元宇宙游戏
QT script document translation (I)
Pytest automated test - easy tutorial (01)
SQL语言-查询语句
[Xunwei dry goods] opencv test of Godson 2k1000 development board
[deploy private warehouse based on harbor] 4 push image to harbor
About daily report plan
News web page display
Starting from scratch (IV) enemy aircraft flying out of the border disappear automatically
Common modules of saltstack
Flutter Container组件
Method to determine whether it is an array
农房一体脚本的心得记录
网狐游戏服务器房间配置向导服务定制功能页实现
Leetcode-9.Palindrome Numbber