并发编程的核心挑战
线程安全性问题
多线程环境下共享资源的竞态条件、数据不一致性。
如何通过锁(synchronized
、ReentrantLock
)或原子类(AtomicInteger
)解决。
// 线程不安全示例
public class Counter {
private int count = 0;
public void increment() { count++; }
}
死锁与活锁
死锁产生的四个必要条件(互斥、占有等待、不可抢占、循环等待)。
活锁的典型场景(线程不断重试但无法推进)。
检测与避免策略(超时机制、资源有序分配)。
// 死锁示例
synchronized (lockA) {
synchronized (lockB) { ... }
}
性能与可伸缩性
上下文切换开销
线程过多导致CPU频繁切换,可通过线程池(ThreadPoolExecutor
)优化。
协程(如Quasar库)或异步编程(CompletableFuture
)的替代方案。
伪共享(False Sharing)
CPU缓存行无效化问题,使用填充(@Contended
)或字段对齐解决。
// 避免伪共享的填充示例
class Data {
@Contended
volatile long value;
}
JVM与硬件的影响
内存可见性
volatile
关键字与Happens-Before规则。
指令重排序问题及内存屏障的作用。
多核CPU的缓存一致性
MESI协议对并发编程的影响,CAS(compareAndSwap
)的实现原理。
高级工具与最佳实践
并发容器
ConcurrentHashMap
的分段锁设计,CopyOnWriteArrayList
的读写分离。
无锁编程
CAS
(AtomicReference
)与ABA
问题的解决方案(版本号标记)。
// CAS示例
AtomicInteger atomicInt = new AtomicInteger(0);
atomicInt.compareAndSet(0, 1);
框架级解决方案
Akka的Actor模型,Spring Reactor的响应式编程范式。
调试与监控
工具链
jstack
排查死锁,JProfiler
分析线程阻塞,Arthas
实时诊断。
设计原则
最小化同步范围,优先使用不可变对象,避免嵌套锁。