面试官问我Java原子操作,我一句话差点让他闭麦!

软件求生 2025-04-22 09:41:23



嗨,大家好!我是你们熟悉的 31 岁程序员大哥哥小米~

最近正在换工作,正好面试了自己超喜欢的一家十八线互联网公司!

不过说真的,这次社招面试我可是吃了不少亏,尤其是碰到并发相关的题目,简直脑瓜嗡嗡的。面试官突然问我:“你知道什么是原子操作吗?Java Concurrency API 里面有哪些Atomic 类?”

???

当时我表面笑嘻嘻,心里 MMP……

回来赶紧复盘查资料,深扒源码,一顿操作猛如虎,今天就把这段血泪教训和大家好好分享一下!如果你也准备社招或者打算换岗,记得收藏好这篇,面试高频考点必备!

什么是原子操作?

咱先来搞清楚原子操作到底是个啥玩意。

原子操作(Atomic Operation),简单来说就是不可再分割的最小操作单元,要么不做,要么做完,中间不可能被打断。

在并发编程里,多个线程可能同时操作同一个变量,假如一个操作不是原子的,线程切换到一半就可能会发生数据不一致的问题。

比如:

你以为这是个简单的 +1 ?其实它是三个步骤:

读取变量 i 的值

将值加 1

写回变量 i

如果多个线程同时执行这个操作,就可能发生线程安全问题。

而原子操作的好处是,无论有多少线程,只要这个操作是原子的,就不会出现乱套的情况。线程 A 做这个事,线程 B 只能等着,或者直接做完互不影响。

Java 怎么实现原子操作?

Java 里的原子性是怎么保证的呢?

我们来看看常见的方式:

1. synchronized(重量级)

咱们最熟悉的 synchronized 关键字,它能保证某个代码块同一时刻只允许一个线程进入,等于是给方法/代码块加了个锁。

不过用多了性能不太行,容易阻塞。

2. Lock(更灵活)

java.util.concurrent.locks 包下的 ReentrantLock,比 synchronized 更灵活,可以手动释放锁,支持可中断、公平锁等高级玩法。

3. 原子类 AtomicXXX(轻量高效!)

这才是我们今天的主角。

基于 CAS(Compare And Swap) 和 volatile 实现,性能比加锁方案要好,适合多线程频繁并发的情况。

Java Concurrency API 中的原子类有哪些?

好,重头戏来了,Java Concurrency API 给我们提供了一堆好用的Atomic 类,我给你整理了个小米专属清单。

常见 Atomic 类汇总

是不是很多!先别慌,小米给你详细说说用法。

核心 Atomic 类实战详解

1、AtomicInteger

核心方法:

get():获取当前值

set(int newValue):设置新值

getAndIncrement():先返回当前值,再自增

incrementAndGet():先自增,再返回值

compareAndSet(int expect, int update):如果当前值等于 expect,才更新为 update,CAS 精髓!

实例演示:

超级简单是不是?

注意这个 compareAndSet,很多原子操作的底层都是靠它搞定的。

2、AtomicReference

作用:原子更新对象引用

比如

这个在多线程下操作对象很有用!

3、AtomicStampedReference

作用:解决 ABA 问题(值变了又变回去,看不出来)

ABA 举个例子:

A:初始值 100,线程1改成 101,线程2又改回 100

B:线程3以为值没变,其实变过

为了避免这种情况,AtomicStampedReference 给对象加个版本号

超稳!

4、LongAdder

作用:高性能计数器,分段锁,减少竞争

适合高并发场景,比 AtomicInteger 性能更好。

建议面试的时候提一下它,面试官会觉得你懂行!

Atomic 原理:CAS + volatile

其实这些 Atomic 类的原理主要靠两个招式:

1、CAS(Compare And Swap)

三个值:内存值 V、旧预期值 A、要更新的新值 B

如果 V == A,说明没人动,更新成 B,成功

如果 V ≠ A,说明被改了,失败,继续重试

JVM 提供的 unsafe.compareAndSwapInt() 方法就是这么干的。

2、volatile

所有 Atomic 变量内部的值都是 volatile 修饰,保证了可见性,线程改了,其他线程立马能看到最新值。

面试技巧总结

说了这么多,来个小米专属面试答题模板:

原子操作是指在多线程环境下,不可被中断的、完整的操作单元,确保数据一致性。

在 Java Concurrency API 中,主要通过Atomic 类提供原子性保障,如 AtomicInteger、AtomicLong、AtomicReference、AtomicStampedReference、LongAdder 等。

它们基于 CAS(Compare And Swap) 和 volatile 实现,避免了传统加锁的性能开销,适用于高并发环境。

记住,面试的时候别一上来就背,带点场景说明,效果更好:

“在高并发计数的场景里,我更推荐用 LongAdder,因为它分段锁降低了竞争,相比 AtomicInteger 性能更好。”

面试官 :“嗯?小伙子你很懂嘛!”

END

今天这篇,算是我跳槽面试踩坑+自我拯救的实录了。

原子操作和 Atomic 类真的很重要,尤其是多线程并发相关的题目,社招、晋升、跳槽基本都少不了。

希望我这篇轻松带故事、带场景、带代码的分享,能帮你在面试里多拿几分!

如果你觉得有用,记得点赞 + 转发 + 收藏啊喂!

小米我会继续分享更多面试经验、源码解析和实战案例,咱们一起卷(不是)成长!

我们下期见!

0 阅读:0

软件求生

简介:从事软件开发,分享“技术”、“运营”、“产品”等。