atomicinteger_AtomicInteger原子类原理解析

d891ac940b561b5d26778391de4bc2a7.gif

点击上方“蓝字”关注我们,每天点亮一个新的技能点。

本文作者:无双老师云析学院VIP课程授课老师

原子操作

  原子操作是指不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会有任何线程上下文切换。   原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中的一部分,将整个操作视作一个整体是原子性的核心特征。

原子类

  在java中提供了很多原子类,主要把这些原子类分成 四大类 。 01f2e82628e1aa9be6380302e14ac019.png

原子更新基本类型或引用类型

  1. AtomicBoolean
原子更新布尔类型,内部使用int类型的value存储1和0表示true和false,底层也是对int类型的原子操作。
  1. AtomicInteger
原子更新int类型。
  1. AtomicLong
原子更新long类型。
  1. AtomicReference
原子更新引用类型,通过泛型指定要操作的类。
  1. AtomicMarkableReference
原子更新引用类型,内部使用Pair承载引用对象及是否被更新过的标记,避免了ABA问题。
  1. AtomicStampedReference
原子更新引用类型,内部使用Pair承载引用对象及更新的邮戳,避免了ABA问题。

原子更新数组中的元素

原子更新数组中的元素,可以更新数组中指定索引位置的元素,这些类主要有:
  1. AtomicIntegerArray
原子更新int数组中的元素。
  1. AtomicLongArray
原子更新long数组中的元素。
  1. AtomicReferenceArray
原子更新Object数组中的元素。

原子更新对象中的字段

原子更新对象中的字段,可以更新对象中指定字段名称的字段,这些类主要有:
  1. AtomicIntegerFieldUpdater
原子更新对象中的int类型字段。
  1. AtomicLongFieldUpdater
原子更新对象中的long类型字段。
  1. AtomicReferenceFieldUpdater
原子更新对象中的引用类型字段。

高性能原子类

高性能原子类,是java8中增加的原子类,它们使用分段的思想,把不同的线程hash到不同的段上去更新,最后再把这些段的值相加得到最终的值,这些类主要有:
  1. Striped64
下面四个类的父类。
  1. LongAccumulator
long类型的聚合器,需要传入一个long类型的二元操作,可以用来计算各种聚合操作,包括加乘等。
  1. LongAdder
long类型的累加器,LongAccumulator的特例,只能用来计算加法,且从0开始计算。
  1. DoubleAccumulator
double类型的聚合器,需要传入一个double类型的二元操作,可以用来计算各种聚合操作,包括加乘等。
  1. DoubleAdder
double类型的累加器,DoubleAccumulator的特例,只能用来计算加法,且从0开始计算。

AtomicInteger使用

package com.example.atomic.atomicinteger.demo;import	java.util.concurrent.atomic.AtomicInteger;/**
* @Author: 无双老师【云析学院:http://yunxiedu.net QQ:3190976240 email:zhouguanya20@163.com】
* @Date: 2020-03-21 16:20
* @Description: AtomicInteger使用方式
*/public class AtomicIntegerDemo {public static void main(String[] args) throws InterruptedException {
test1();
test2();
}private static void test1() throws InterruptedException {
Counter counter = new Counter();// 100个线程for (int i = 0; i < 10; i++) {// 每个线程对count累加10次new Thread(() -> {for (int j = 0; j < 1000; j++) {
counter.addCount();
}
}).start();
}
Thread.sleep(1000);
System.out.println("count = " + counter.getCount());
}private static void test2() throws InterruptedException {/**
* 原子性的int
*/
AtomicInteger count = new AtomicInteger();// 100个线程for (int i = 0; i < 10; i++) {// 每个线程对count累加10次new Thread(() -> {for (int j = 0; j < 1000; j++) {
count.incrementAndGet();
}
}).start();
}
Thread.sleep(1000);
System.out.println("count = " + count.get());
}
}/**
* volatile修饰的计数器
*/private volatile static int count = 0;public void addCount() {
count++;
}public int getCount() {return count;
}

AtomicInteger原理

AtomicInteger声明

public class AtomicInteger extends Number implements java.io.Serializable

Unsafe类的使用

// setup to use Unsafe.compareAndSwapInt for updatesprivate 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); }
}

AtomicInteger属性

 private volatile int value;

AtomicInteger构造器

    /**
* Creates a new AtomicInteger with the given initial value.
*
* @param initialValue the initial value
*/public AtomicInteger(int initialValue) {
value = initialValue;
}/**
* Creates a new AtomicInteger with initial value {@code 0}.
*/public AtomicInteger() {
}

AtomicInteger自增

    /**
* Atomically increments by one the current value.
*
* @return the updated value
*/public final int incrementAndGet() {return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
调用Unsafe类的方法如下。
    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即CAS方式修改int值。 AtomicInteger.incrementAndGet方法自增的原理:
  1. 调用unsafe.getAndAddInt方法
  2. unsafe.getAndAddInt方法通过自旋的方式,每次尝试通过CAS方法对原值进行累加。如果累加失败,将进入下一次循环。如果累加成功,则自旋结束。

免费技术直播

4dcb8a1a3c27b094e6a1469f5b57811e.png点击图片直达课堂4dcb8a1a3c27b094e6a1469f5b57811e.png

0cfc4dd3644d6c344df1e579d0ab85e2.png

0529da773f6957f588dd437aa665a55f.png

觉得不错,请点个在看吧~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值