网站首页 > 知识剖析 正文
一、高频面试题全景解析
1. volatile如何保证可见性?底层原理是什么?
// 典型场景:多线程共享变量可见性问题
public class VisibilityDemo {
// 不加volatile时,线程可能读取到旧值
private volatile boolean flag = true;
public void start() {
new Thread(() -> {
while (flag) { /* 空循环 */ }
System.out.println("线程退出");
}).start();
new Thread(() -> {
flag = false;
}).start();
}
}
核心答案:
- volatile通过内存屏障(Memory Barrier)和缓存一致性协议(如MESI)实现可见性
- 写操作后强制刷新主内存,读操作前强制从主内存读取
- 底层通过JVM的StoreStore、StoreLoad等屏障指令实现
2. synchronized与ReentrantLock底层实现差异
// ReentrantLock显式锁实战
public class LockDemo {
private final ReentrantLock lock = new ReentrantLock(true); // 公平锁
public void accessResource() {
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
}
}
核心对比:
特性 | synchronized | ReentrantLock |
实现方式 | JVM层面(monitorenter) | JDK层面(AQS) |
锁类型 | 非公平锁 | 支持公平/非公平 |
中断响应 | 不支持 | 支持lockInterruptibly() |
条件变量 | 单个 | 可创建多个Condition对象 |
3. 线程池参数配置黄金法则
// 阿里推荐线程池配置模板
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数(CPU密集型建议N+1)
10, // 最大线程数(IO密集型建议2N)
60L, TimeUnit.SECONDS, // 保活时间
new LinkedBlockingQueue<>(100), // 任务队列
new ThreadFactoryBuilder().setNameFormat("order-pool-%d").build(), // 命名规范
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
关键参数解析:
- 队列选择:
- SynchronousQueue:直接传递,适合短任务
- LinkedBlockingQueue:无界队列,易导致OOM
- ArrayBlockingQueue:有界队列,需合理评估容量
二、真实场景案例拆解
案例1:订单超时未支付自动关闭
// 线程安全的时间轮算法实现
public class TimeWheel {
private final ConcurrentHashMap<Long, Order> orderMap = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public void addOrder(Order order) {
orderMap.put(order.getId(), order);
scheduler.schedule(() -> {
if (order.getStatus() == UNPAID) {
order.close();
orderMap.remove(order.getId());
}
}, 30, TimeUnit.MINUTES);
}
}
技术要点:
- 使用ConcurrentHashMap保证线程安全
- 单线程调度避免任务竞争
- 幂等性处理防止重复关单
案例2:秒杀系统库存扣减
// 基于CAS的乐观锁实现
public class StockService {
private AtomicInteger stock = new AtomicInteger(100);
public boolean reduceStock() {
int current;
do {
current = stock.get();
if (current <= 0) return false;
} while (!stock.compareAndSet(current, current - 1));
return true;
}
}
优化策略:
- 分段锁降低竞争粒度
- Redis+Lua脚本保证原子性
- 本地缓存+异步扣减提升吞吐量
三、必知必会考点总结
- ThreadLocal内存泄漏根源
- 弱引用解决Entry的Key泄漏
- 必须手动remove()清理Value
- 死锁检测与预防
- jstack生成线程快照分析
- 统一加锁顺序避免循环等待
- CompletableFuture异步编排
CompletableFuture.supplyAsync(() -> getPrice())
.thenCombineAsync(getStock(), (price, stock) -> calcTotal())
.exceptionally(ex -> handleError());
四、面试加分技巧
- 源码级理解:AQS的CLH队列实现、ThreadPoolExecutor的Worker机制
- 性能调优:通过jstack分析线程阻塞点、jstat监控线程状态
- 行业实践:美团动态线程池配置、阿里Sentinel线程隔离策略
结语:掌握这些核心要点,面试通过率提升80%!转发收藏本文,备战金九银十,助你斩获心仪Offer!
猜你喜欢
- 2025-09-21 5种方法,快速地将多个符合条件的内容归类至一个单元格中
- 2025-09-21 C#开发学习人工智能的第一步_人工智能开发的编程语言
- 2025-09-21 LeadTools中文入门教程(5):读取和编写条形码
- 2025-09-21 深入CompletableFuture源码:一文搞懂异步编程核心原理
- 2025-09-21 Java 8:CompletableFuture终极指南
- 2025-09-21 Visual Studio Package 插件开发(Visual Studio SDK)
- 2025-09-21 特斯拉AI芯片深度解读_特斯拉ai芯片深度解读视频
- 2025-09-21 高级程序员必备:分治算法分享_分冶算法
- 2025-09-21 MapReduce过程详解及其性能优化(详细)
- 2025-09-21 微调自己的SAM 2 分割模型_微调自己的sam+2+分割模型是什么意思
- 最近发表
-
- 5种方法,快速地将多个符合条件的内容归类至一个单元格中
- C#开发学习人工智能的第一步_人工智能开发的编程语言
- LeadTools中文入门教程(5):读取和编写条形码
- 深入CompletableFuture源码:一文搞懂异步编程核心原理
- Java 8:CompletableFuture终极指南
- Java多线程面试必问题:从volatile到线程池,阿里P8整理核心答案
- Visual Studio Package 插件开发(Visual Studio SDK)
- 特斯拉AI芯片深度解读_特斯拉ai芯片深度解读视频
- 高级程序员必备:分治算法分享_分冶算法
- MapReduce过程详解及其性能优化(详细)
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)