AtomicInteger源码解析
1.BIO、NIO、AIO的区别2.Controller是线程安全吗3.为什么多线程下会有线程安全问题4.volatile为什么没有原子性?5.JVM的四种内存屏障6.synchronized关键字原理7.synchronized 锁升级 锁降级8.自旋锁、阻塞锁、可重入锁使用解析9.线程间实现通信的几种方式10.ThreadPoolExecutor线程池参数设置技巧11.关于线程同步(7种同步方式)12.ThreadLocal可能引起的内存泄露13.乐观锁的一种实现方式——CAS
14.AtomicInteger源码解析
15.ReentrantLock源码解析1--获得非公平锁与公平锁lock()16.ReentrantLock源码解析2--释放锁unlock()17.ReentrantLock源码解析3--优先响应中断的lockInterruptibly18.ReentrantLock总结19.ArrayBlockingQueue源码解析20.LinkedBlockingQueue源码解析21.Timer / TimerTask 源码解析22.Delay延迟队列1、原子类
- 可以实现一些原子操作
- 基于CAS
下面就以AtomicInteger为例。
2、AtomicInteger
在没有AtomicInteger之前,对于一个Integer的线程安全操作,是需要使用同步锁来实现的,当然现在也可以通过ReentrantLock来实现,但是最好最方便的实现方式是采用AtomicInteger。
具体示例:

package com.collection.test; import java.util.concurrent.atomic.AtomicInteger; /** * 原子类的测试 */ public class AtomicTest { private static AtomicInteger atomicInteger = new AtomicInteger(); //获取当前值 public static void getCurrentValue(){ System.out.println(atomicInteger.get());//-->0 } //设置value值 public static void setValue(){ atomicInteger.set(12);//直接用12覆盖旧值 System.out.println(atomicInteger.get());//-->12 } //根据方法名称getAndSet就知道先get,则最后返回的就是旧值,如果get在后,就是返回新值 public static void getAndSet(){ System.out.println(atomicInteger.getAndSet(15));//-->12 } public static void getAndIncrement(){ System.out.println(atomicInteger.getAndIncrement());//-->15 } public static void getAndDecrement(){ System.out.println(atomicInteger.getAndDecrement());//-->16 } public static void getAndAdd(){ System.out.println(atomicInteger.getAndAdd(10));//-->15 } public static void incrementAndGet(){ System.out.println(atomicInteger.incrementAndGet());//-->26 } public static void decrementAndGet(){ System.out.println(atomicInteger.decrementAndGet());//-->25 } public static void addAndGet(){ System.out.println(atomicInteger.addAndGet(20));//-->45 } public static void main(String[] args) { AtomicTest test = new AtomicTest(); test.getCurrentValue(); test.setValue(); //返回旧值系列 test.getAndSet(); test.getAndIncrement(); test.getAndDecrement(); test.getAndAdd(); //返回新值系列 test.incrementAndGet(); test.decrementAndGet(); test.addAndGet(); } }
源代码:

private volatile int value;// 初始化值 /** * 创建一个AtomicInteger,初始值value为initialValue */ public AtomicInteger(int initialValue) { value = initialValue; } /** * 创建一个AtomicInteger,初始值value为0 */ public AtomicInteger() { } /** * 返回value */ public final int get() { return value; } /** * 为value设值(基于value),而其他操作是基于旧值<--get() */ public final void set(int newValue) { value = newValue; } public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } /** * 基于CAS为旧值设定新值,采用无限循环,直到设置成功为止 * * @return 返回旧值 */ public final int getAndSet(int newValue) { for (;;) { int current = get();// 获取当前值(旧值) if (compareAndSet(current, newValue))// CAS新值替代旧值 return current;// 返回旧值 } } /** * 当前值+1,采用无限循环,直到+1成功为止 * @return the previous value 返回旧值 */ public final int getAndIncrement() { for (;;) { int current = get();//获取当前值 int next = current + 1;//当前值+1 if (compareAndSet(current, next))//基于CAS赋值 return current; } } /** * 当前值-1,采用无限循环,直到-1成功为止 * @return the previous value 返回旧值 */ public final int getAndDecrement() { for (;;) { int current = get(); int next = current - 1; if (compareAndSet(current, next)) return current; } } /** * 当前值+delta,采用无限循环,直到+delta成功为止 * @return the previous value 返回旧值 */ public final int getAndAdd(int delta) { for (;;) { int current = get(); int next = current + delta; if (compareAndSet(current, next)) return current; } } /** * 当前值+1, 采用无限循环,直到+1成功为止 * @return the updated value 返回新值 */ public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next;//返回新值 } } /** * 当前值-1, 采用无限循环,直到-1成功为止 * @return the updated value 返回新值 */ public final int decrementAndGet() { for (;;) { int current = get(); int next = current - 1; if (compareAndSet(current, next)) return next;//返回新值 } } /** * 当前值+delta,采用无限循环,直到+delta成功为止 * @return the updated value 返回新值 */ public final int addAndGet(int delta) { for (;;) { int current = get(); int next = current + delta; if (compareAndSet(current, next)) return next;//返回新值 } } /** * 获取当前值 */ public int intValue() { return get(); }
说明:使用与源代码都简单到爆了!自己看看注释。
注意:
- value是volatile的,关于volatile的相关内容见《附2 volatile》,具体链接:http://www.cnblogs.com/java-zhao/p/5125698.html
- 单步操作:例如set()是直接对value进行操作的,不需要CAS,因为单步操作就是原子操作。
- 多步操作:例如getAndSet(int newValue)是两步操作-->先获取值,在设置值,所以需要原子化,这里采用CAS实现。
- 对于方法是返回旧值还是新值,直接看方法是以get开头(返回旧值)还是get结尾(返回新值)就好
- CAS:比较CPU内存上的值是不是当前值current,如果是就换成新值update,如果不是,说明获取值之后到设置值之前,该值已经被别人先一步设置过了,此时如果自己再设置值的话,需要在别人修改后的值的基础上去操作,否则就会覆盖别人的修改,所以这个时候会直接返回false,再进行无限循环,重新获取当前值,然后再基于CAS进行加减操作。
- 如果还是不懂CAS,类比数据库的乐观锁。
补充一个东西:

// 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的所有属性,其中value存的是当前值,而当前值存放的内存地址可以通过valueOffset来确定。实际上是“value字段相对Java对象的起始地址的偏移量”

public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了