最近研究 Java 的并发包,了解到关于原子类的操作,这里将自己了解到的贴出来功能大家参考一下,有什么不足的地方还望大家指正,及时更新。
AtomicInteger 是 Java 1.5 开始在 atomic 包提供的可以在多线程条件下安全的访问和操作 int 数据类型的类,之前我们对操作 int 数据类型的时候,通常用 i++、i-- 等操作,但是这样的操作在多线程下是不安全的,因为这样的操作并不是原子的,下面我们看看例子:
public class IntegerTest { private static int number = 0; private final ststic int count = 1000000; public static void main(String[] args){ Runnable runnable1 = createRunnable(); Runnable runnable2 = createRunnable(); //这里执行 2000000 次 new Thread(runnable1).start(); new Thread(runnable2).start(); try{ Thread.sleep(1000); // 打印 System.out.println(number); } catch (InterruptedException e) { e.printStackTrace(); } } public static Runnable createRunnable(){ return ()->{ for(int i = 0; i < count; i++){ number++; } } }}复制代码
经测试,最后的打印结果是:1048708。当然,每次打印的值都不一样,但是这正说明了在多线程下,针对 int 的操作是不安全的。
以后针对这样的场景可以使用 AotmicInteger 类,它帮助我们解决了多线程下的安全问题,并且提供了更所的操作方法,下面介绍一下这个类的方法介绍:
1、byteValue() —— 这个方法继承自 Number 类,以 byte 类型返回当前值;2、shortValue() —— 这个方法继承自 Number 类,以 short 类型返回当前值;3、intValue() —— 这个方法继承自 Number 类,以 int 类型返回当前值;4、longValue() —— 这个方法继承自 Number 类,以 long 类型返回当前值;5、floatValue() —— 这个方法继承自 Number 类,以 float 类型返回当前值;6、doubleValue() —— 这个方法继承自 Number 类,以 double 类型返回当前值;7、getAndIncrement() —— 这个方法先获取当前值,然后再自增 1 (类似 i++);8、incrementAndGet() —— 这个方法先自增 1 (类似 ++i),然后再返回这个值;9、getAndIncrement() —— 这个方法先获取当前值,然后再自减 1 (类似 i--);10、incrementAndGet() —— 这个方法先自减 1 (类似 --i),然后再返回这个值;11、addAndGet(int value) —— 先加上 value,然后返回之后的值;12、getAndAdd(int value)—— 先获取当前值,然后自己在加上 value;//从这儿我们可以发现这个类的方法命名很直观,从名字就能知道这个方法的作用13、compareAndSet(int first, int second) —— 如果当前值等于 first,返回 true,同时将值更新为 second,否则返回 false,但不会更新;14、weakCompareAndGet(int first, int second) —— 与 compareAndSet 一样(源码是一样);15、getAndSet(int value) —— 先获取当前值,然后再设置为 value;16、getAndUpdate(IntUnaryOperator op) —— 这个方法是 Java 1.8 开始提供的,这个方法自身返回当前值。同时会把 op 的返回值设置为新值,具体参考 IntUnaryOperator 类,关于 function 包使用方法以后会介绍;17、updateAndGet(IntUnaryOperator op) —— 这个方法先将 op 的返回值作为新值,然后返回这个新值;18、getAndAccumulate(int val, IntBinaryOperator op) —— 这个方法返回值,然后将当前值和 val 作为参数传给 op,将 op 的返回值设置为新值;19、accumulateAndGet(int val, IntBinaryOperator op) —— 这个方法先将当前值和 val 作为参数传给 op,将 op 的返回值设置为新值,然后返回;20、set(int val) —— 设置;21、lazySet(int val) —— 设置(与 set 一样,区别暂时还不知,但实现方式不一样)。复制代码
以上就是 AtomicInteger 类的全部方法了,但是我在阅读源码的时候还发现了一些疑惑的地方,比如 getAndAccumulate 方法在内部的实现中循环调用了 compareAndSet 方法,这儿有什么必要循环调用呢?暂时还不清楚,但这大概就是我们是我们在探索的道路上越走越远的一大动力吧!以后有什么新的发现会及时更新,如有人清楚,还望告知。
谢谢大家,请大家持续关注!