
1. JUC并发编程核心概念解析Java并发编程中的JUCjava.util.concurrent包是Java 5引入的重要并发工具库它提供了一系列比原生synchronized更强大的并发控制机制。在实际高并发场景中JUC组件往往能带来显著的性能提升。以CountDownLatch为例它的核心原理是通过一个计数器来实现线程协调// 典型用法示例 CountDownLatch latch new CountDownLatch(3); new Thread(() - { // 任务执行 latch.countDown(); }).start(); latch.await(); // 阻塞直到计数器归零这种机制相比传统的wait/notify有三大优势计数器状态可视化调试更方便不需要 synchronized 同步块支持一次性释放多个等待线程关键经验在初始化CountDownLatch时计数器值应该等于需要等待的独立任务数而不是线程数。我曾在一个订单处理系统中错误设置为线程池大小导致永远无法触发完成条件。2. 原子操作类深度剖析java.util.concurrent.atomic包下的原子类使用CAS(Compare-And-Swap)实现无锁线程安全。以AtomicInteger为例AtomicInteger counter new AtomicInteger(0); // 线程安全的自增 int newValue counter.incrementAndGet();其底层实现依赖于Unsafe类的compareAndSwapInt方法该方法是native方法最终会调用CPU的原子指令。在x86架构上对应的是LOCK CMPXCHG指令。性能对比测试数据操作类型100万次操作耗时(ms)synchronized120AtomicInteger45volatile30(但非线程安全)踩坑记录CAS存在ABA问题即值从A→B→A的变化无法被检测到。在支付状态变更场景中我曾因此导致重复扣款。解决方案是使用AtomicStampedReference。3. 并发容器实战技巧JUC提供的并发容器在HashMap等传统集合的基础上实现了线程安全3.1 ConcurrentHashMap分段锁机制JDK7中的ConcurrentHashMap采用分段锁设计默认分为16个Segment。而JDK8之后改为数组链表红黑树结构CASsynchronized实现粒度更细的锁控制ConcurrentHashMapString, Integer map new ConcurrentHashMap(); // 线程安全的putIfAbsent map.putIfAbsent(key, 1);3.2 CopyOnWriteArrayList适用场景适合读多写少的场景写入时复制整个数组CopyOnWriteArrayListString list new CopyOnWriteArrayList(); list.add(item); // 触发数组复制性能提示当预期修改操作超过总操作量的10%时应考虑其他方案因为频繁复制会导致GC压力。4. 线程池最佳实践ThreadPoolExecutor的核心参数配置直接影响系统稳定性ThreadPoolExecutor executor new ThreadPoolExecutor( 5, // 核心线程数 10, // 最大线程数 60, // 空闲时间(秒) TimeUnit.SECONDS, new LinkedBlockingQueue(100) // 任务队列 );配置经验公式CPU密集型核心线程数 CPU核数 1IO密集型核心线程数 CPU核数 × 2监控建议继承ThreadPoolExecutor并重写beforeExecute/afterExecute方法添加监控日志。我们曾通过这种方式发现任务执行时间异常导致的线程堆积问题。5. Lock显式锁进阶用法ReentrantLock相比synchronized提供了更灵活的控制ReentrantLock lock new ReentrantLock(); Condition condition lock.newCondition(); lock.lock(); try { while(!conditionMet) { condition.await(); // 类似Object.wait() } // 业务逻辑 condition.signal(); // 类似Object.notify() } finally { lock.unlock(); // 必须放在finally块 }锁选型决策树需要尝试获取锁→ ReentrantLock.tryLock()需要公平性→ new ReentrantLock(true)需要读写分离→ ReentrantReadWriteLock6. 并发编程常见陷阱6.1 死锁检测与预防使用jstack检测死锁jstack -l pid | grep -A 10 deadlock预防策略按固定顺序获取多把锁设置锁超时时间使用Lock.tryLock()6.2 线程上下文切换开销测试表明当线程数超过CPU核心数2倍时上下文切换开销会显著增加。可以通过以下命令监控vmstat 1 # 查看cs字段(上下文切换次数)7. 性能优化实战案例在某电商秒杀系统中我们通过以下JUC优化将QPS从500提升到3000使用LongAdder替代AtomicLong计数器优点分段累加减少CAS竞争缺点空间消耗稍大采用ConcurrentHashMap缓存商品库存使用computeIfAbsent原子化初始化避免双重检查锁定模式自定义ThreadPoolExecutor拒绝策略记录拒绝的任务信息触发降级处理逻辑new ThreadPoolExecutor.CallerRunsPolicy() { Override public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { // 自定义记录和降级逻辑 log.warn(Task rejected: r); fallbackProcessor.process(r); } }对于高并发场景下的资源竞争我发现采用分层加锁策略往往能取得更好效果。比如在订单系统中先对用户ID哈希取模分段再在段内加细粒度锁这样既保证了线程安全又避免了全局锁的性能瓶颈。