一、底层逻辑基础
1.1 线程模型与操作系统关联
- JVM 线程与操作系统线程:Java 线程是映射到操作系统原生线程的,在 Linux 系统中通过 pthread 实现,Windows 使用 Win32 线程模型。
- 线程调度开销:
- 上下文切换成本:保存/恢复寄存器、程序计数器、栈状态等(约 1-10μs)。
- 缓存失效:频繁切换导致 CPU 缓存命中率下降。
- 线程状态转换:
- java
- // 线程状态枚举示例(简化版)public enum ThreadState { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED}
1.2 内存可见性原理
- CPU 缓存架构:
- L1/L2/L3 缓存层级结构
- 缓存一致性协议(MESI 协议):
- Modified(修改)
- Exclusive(独占)
- Shared(共享)
- Invalid(无效)
- Java 内存模型(JMM):
- 主内存与工作内存的抽象
- happens-before 规则:
- 程序顺序规则
- 锁规则
- volatile 变量规则
- 传递性规则
1.3 原子操作实现
- CAS(Compare-And-Swap):
- java
- // Unsafe 类中的 CAS 操作示例public final native boolean compareAndSwapInt(Object o, long offset, int expected, int x);
- CPU 指令支持:
- x86:LOCK CMPXCHG
- ARM:LDREX/STREX
二、核心并发组件
2.1 synchronized 优化
- 锁升级过程:
- 无锁 → 偏向锁 → 轻量级锁 → 重量级锁
- 锁消除与锁粗化:
- java
- // 锁消除示例public String concatString(String s1, String s2) { // JIT 可能消除 synchronized StringBuffer sb = new StringBuffer(); // 非线程安全版本可能被优化 sb.append(s1); sb.append(s2); return sb.toString();}
2.2 AQS 框架解析
- 模板方法模式应用:
- java
- // AbstractQueuedSynchronizer 核心方法public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt();}
- CLH 队列变种:
- 双向链表结构
- 每个节点保存前驱节点状态
2.3 并发容器实现
- ConcurrentHashMap 分段锁(Java 7):
- java
- // Java 7 Segment 结构static final class Segment<K,V> extends ReentrantLock implements Serializable { volatile HashEntry<K,V>[] table; // ...}
- Java 8 CAS+synchronized 优化:
- 桶级细粒度锁
- 红黑树优化(当链表长度 > 8 时)
三、实践技巧
3.1 线程池配置策略
- 容量计算模型:
- 核心线程数 = Ncpu * Ucpu * (1 + W/C)// Ncpu: CPU核心数// Ucpu: 目标CPU利用率// W/C: 等待时间与计算时间比率
- 拒绝策略选择:
- java
- // 自定义拒绝策略示例public class CustomRejectionPolicy implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { // 实现降级逻辑 log.warn("Task rejected, executing fallback"); new Thread(r).start(); // 谨慎使用 }}
3.2 并发工具类应用
- CountDownLatch 场景:
- java
- // 多线程初始化场景CountDownLatch latch = new CountDownLatch(3);ExecutorService executor = Executors.newFixedThreadPool(3); for (int i = 0; i < 3; i++) { executor.submit(() -> { // 初始化操作 latch.countDown(); });} latch.await(); // 阻塞直到所有初始化完成
- CyclicBarrier 循环屏障:
- java
- // 多阶段任务同步CyclicBarrier barrier = new CyclicBarrier(3, () -> { System.out.println("所有线程到达阶段1");});
3.3 性能优化技巧
- 伪共享避免:
- java
- // 使用 @Contended 注解(Java 8+)@sun.misc.Contendedclass VolatileLong { volatile long value;}
- 无锁数据结构选择:
- Disruptor 环形队列
- LongAdder 分段计数器
四、常见陷阱与解决方案
4.1 死锁诊断
- 死锁检测工具:
- bash
- # Linux 死锁检测jstack <pid> | grep -A 50 "deadlock"
- 预防策略:
- 固定加锁顺序
- 使用 tryLock 超时机制
4.2 线程饥饿问题
- 解决方案:
- 公平锁与非公平锁选择
- 工作窃取算法(ForkJoinPool)
4.3 并发修改异常
- CopyOnWrite 模式:
- java
- // CopyOnWriteArrayList 实现原理public boolean add(E e) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len + 1); newElements[len] = e; setArray(newElements); return true; } finally { lock.unlock(); }}
五、高级主题
5.1 Fiber 与协程
- Project Loom 预览:
- 虚拟线程(Virtual Thread)
- 连续调度模型
5.2 Reactive Streams
- 响应式编程模型:
- java
- // WebFlux 示例public Mono<ServerResponse> getData(ServerRequest request) { return Mono.fromCallable(() -> { // 阻塞调用转换为异步 return blockingRepository.findById(request.pathVariable("id")); }).subscribeOn(Schedulers.boundedElastic()) .flatMap(data -> ok().bodyValue(data));}
5.3 分布式并发控制
- 分布式锁实现:
- java
- // Redisson 分布式锁示例RLock lock = redissonClient.getLock("orderLock");try { boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS); if (isLocked) { // 执行业务逻辑 }} finally { lock.unlock();}
总结
Java 并发编程的演进方向:
- 更细粒度的锁:从对象锁到分段锁再到 CAS 操作
- 更高效的同步机制:AQS 框架、并发容器优化
- 更灵活的编程模型:从线程池到响应式再到虚拟线程
- 更强大的诊断工具:Async Profiler、JFR 等
建议学习路径:
- 掌握基础同步机制(synchronized/volatile)
- 深入 AQS 框架原理
- 实践主流并发容器
- 学习响应式编程模型
- 关注 Java 新特性(如 Loom 项目)