并发基础概念
竞态条件:多线程读写共享变量,结果依赖时序。原子性:操作不可分割;i++ 非原子。可见性:一线程写,另一线程未必立即可见,需 volatile 或锁。有序性:指令重排,happens-before 规则约束。
Java 内存模型:unlock → lock、volatile 写 → 读、线程 start/join 等建立 happens-before。
synchronized 与 volatile
synchronized锁对象监视器,保证互斥与可见性。volatile保证可见性与禁止部分重排,不保证复合操作原子性。- 双重检查锁定单例需
volatile防半初始化对象暴露。
public class Singleton {
private static volatile Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
Lock 与 AQS
ReentrantLock 基于 AQS 队列管理等待线程。ReadWriteLock 读多写少场景提升吞吐。StampedLock 乐观读适合读极多。
死锁四条件:互斥、占有且等待、不可抢占、循环等待。排查用 jstack;预防按序加锁、超时 tryLock。
线程池 ThreadPoolExecutor
ExecutorService pool = new ThreadPoolExecutor(
4, 8, 60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100),
new ThreadPoolExecutor.CallerRunsPolicy()
);
| 拒绝策略 | 行为 | |---|---| | AbortPolicy | 抛异常 | | CallerRunsPolicy | 调用线程执行 | | DiscardOldestPolicy | 丢队首 | | DiscardPolicy | 静默丢弃 |
勿用 Executors.newFixedThreadPool 无界队列可能 OOM。异步任务注意异常处理器与 MDC 传递。
并发容器与工具
ConcurrentHashMap:分段/CAS,高并发读写下表。CopyOnWriteArrayList:读多写少,写时复制。CountDownLatch/CyclicBarrier/Semaphore:协调多线程阶段。
面试高频
- ThreadLocal 原理与内存泄漏(线程池复用需 remove)。
- 公平锁 vs 非公平。
- happens-before 举例。
- Go 侧:goroutine、channel、mutex,对比线程模型。