Java并发编程面试题

2025年 阅读约 13 分钟 面试指南 · Java面试

深入Java并发编程面试核心考点,涵盖线程池、锁机制、volatile、CAS、AQS等高频面试题,附详细解答。

一句话总结

Java 并发是面试的重头戏,核心考点:线程池(7参数+4拒绝策略)、锁机制(synchronized 锁升级 vs ReentrantLock)、volatile(可见性+禁止重排序)、CAS(乐观锁+ABA问题)、AQS(CLH队列+state管理)。每个知识点都有对应的深度解析文章

线程池

Q:线程池的核心参数有哪些?

ThreadPoolExecutor有7个核心参数:

1. corePoolSize:核心线程数,即使空闲也不会回收
2. maximumPoolSize:最大线程数
3. keepAliveTime:非核心线程的空闲存活时间
4. unit:存活时间单位
5. workQueue:任务等待队列
6. threadFactory:线程工厂
7. handler:拒绝策略

执行流程:核心线程→任务队列→非核心线程→拒绝策略

📖 深入阅读:线程池核心参数与执行流程 · 线程生命周期与状态 · wait vs sleep

锁机制

Q:synchronized和ReentrantLock的区别?

synchronized:JVM层面,自动加锁释放锁,不可中断,非公平锁。

ReentrantLock:API层面,手动加锁释放锁,可中断,可公平可非公平,支持Condition条件变量。

synchronized锁升级过程:无锁→偏向锁→轻量级锁→重量级锁。JDK 6引入锁升级优化,大部分情况下不需要重量级锁。

📖 深入阅读:synchronized 底层实现 · ReentrantLock vs synchronized · 死锁排查与预防

volatile关键字

Q:volatile的作用和原理?

volatile有两个作用:可见性禁止指令重排序

可见性:volatile变量的写操作会强制刷新到主内存,读操作会从主内存读取最新值。

禁止指令重排序:通过内存屏障(Memory Barrier)实现。写操作前插入StoreStore屏障,写操作后插入StoreLoad屏障;读操作前插入LoadLoad屏障,读操作后插入LoadStore屏障。

注意:volatile不保证原子性。i++操作即使i是volatile的,也不是线程安全的。

📖 深入阅读:volatile 关键字详解 · Java 内存模型 JMM · ThreadLocal 原理

CAS与AQS

Q:什么是CAS?有什么问题?

CAS(Compare And Swap)是比较并交换,是一种乐观锁的实现方式。它包含三个操作数:内存值V、预期值A、新值B。只有当V等于A时,才将V更新为B。

CAS的问题:
1. ABA问题:值从A变为B再变为A,CAS认为没有变化。解决:AtomicStampedReference
2. 自旋开销:竞争激烈时CAS不断失败重试,消耗CPU
3. 只能保证单个变量的原子操作

Q:AQS是什么?

AQS(AbstractQueuedSynchronizer)是Java并发包的核心框架,ReentrantLock、Semaphore、CountDownLatch等都基于AQS实现。AQS维护一个volatile int state和FIFO等待队列。

📖 深入阅读:CAS 原理与 ABA 问题 · AQS 框架详解 · CountDownLatch/CyclicBarrier/Semaphore

实战场景

场景:自定义线程池 + CountDownLatch 批量处理

// 自定义线程池处理批量任务 ThreadPoolExecutor executor = new ThreadPoolExecutor( 4, 8, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), new ThreadPoolExecutor.CallerRunsPolicy() ); List<String> tasks = Arrays.asList("task1", "task2", "task3"); CountDownLatch latch = new CountDownLatch(tasks.size()); for (String task : tasks) { executor.submit(() -> { try { processTask(task); } finally { latch.countDown(); } }); } latch.await(30, TimeUnit.SECONDS); // 最多等30秒 executor.shutdown();