概述
详解java并发原子类AtomicInteger
1.1:AtomicInteger是干什么的
多线程修改Interger变量会导致结果不正确,所以设置的一个基于多线程并且基于原子类操作的Integer类,多线程下能够保证线程安全
1.2:AtomicInteger是如何使用的
AtomicInteger atomicInteger = new AtomicInteger(1);
atomicInteger.addAndGet(2);
System.out.println(atomicInteger.get());
atomicInteger.getAndAdd(3);
System.out.println(atomicInteger.get());
1.3:AtomicInteger是如何实现的
private volatile int value;
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); }
}
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
public final int get() {
return value;
}
addAndget方法内部定义的一个死循环,先通过get()方法得到当前的value值,然后加上2,加完之后使用CAS原子操作让当前值加上2得到3,在并发的过程中,CAS原子操作不一定成功,所以这个定义的for()死循环,成功返回正确的数据,整个过程不会出现多线程处理错误的问题,打个比方,当前线程A得到的current为1,线程B的带的current也为Current1,线程A的next为2,进程CAS操作成功之后就会将value修改为3了,这个时候线程B的next变为3,当线程B进程CAS操作的时候,由于expect是3而不是期望的3了。所以会CAS失败,下一次循环得到的current为3。
这里还有几个注意点
1:get方法回去的value变量时用volatile修饰的,解决的线程的可见性
2:CAS的的实现依赖于CPU提供更多特殊指令,X86CPU提供的cmpxchg指令,在处理器上CAS是一个非常轻量级的操作,其他处理器可能指令不同
3:Unsafe类是一个可以执行不安全、容易犯错的操作的一个特殊类,里面定义了一些native本地方法的类(本地方法在哪里放着)
1.4:Automatic和其它比较存在什么问题
1:CAS导致的ABA问题
2:for循环存在失败重试机制,但是这里隐含的一个假设。线程之间资源竞争是短暂的,大多数情况下,确实大部分重试一次就获得成功,但是凡事都有意外,在有需要的情况下,要考虑下自旋的次数,一面过度消耗CPU
最后
以上就是漂亮犀牛为你收集整理的详解java并发原子类AtomicInteger的全部内容,希望文章能够帮你解决详解java并发原子类AtomicInteger所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复