Java 并发编程经典模型

按使用场景分类:同步屏障模型、线程等待通知、流量控制、任务分发、异步编排、线程协作锁模型,附带代码、适用场景、对比。

一、屏障同步类(多线程互相等待/统一触发)

1. 双 CountDownLatch

启动门 + 结束门,主线程下发统一信号,精准瞬时并发压测。

2. CyclicBarrier 循环屏障模型

特点:可复用,N个线程互相等待,全部到达屏障点才放行
适用:多阶段并行计算(分块计算→汇总)、多线程分批同步。

// 5个线程凑齐才放行,屏障回调
CyclicBarrier barrier = new CyclicBarrier(5, () -> {
    System.out.println("一批线程全部到达,执行汇总任务");
});
for (int i = 0; i < 5; i++) {
    new Thread(() -> {
        try {
            // 各自执行业务
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + "到达屏障");
            barrier.await(); // 等待其他线程
            // 全部到齐后一起执行后续逻辑
            System.out.println("批量任务并行执行");
        } catch (Exception e) {}
    }).start();
}

区别双Latch:线程之间互相等,不是主线程发号施令;支持重置,可循环多批执行。

3. Phaser 分段相位屏障(高级CyclicBarrier)

支持动态增减线程、多阶段分段等待,适合分阶段并行任务、批量文件分段处理。
阶段1读取文件 → 阶段2解析 → 阶段3入库,每个阶段所有线程完成才进入下一阶段。

二、流量控制/限流模型(控制并发数量)

1. Semaphore 信号量模型(并发窗口控制)

控制同一时间最多N个线程执行,限流、连接池、资源抢占。

// 最多同时3个并发
Semaphore sem = new Semaphore(3);
for (int i = 0; i < 10; i++) {
    new Thread(() -> {
        try {
            sem.acquire(); // 获取许可,无许可阻塞
            // 受限资源操作:DB/第三方接口
            Thread.sleep(500);
        } finally {
            sem.release(); // 归还许可
        }
    }).start();
}

场景:接口限流、数据库连接控制、爬虫并发限制。

2. BoundedThreadPool 有界线程池模型

Executors/FixedThreadPool + 有界队列 + 拒绝策略,底层也是信号量思想,系统级流量控制。

三、等待通知协作模型(生产者消费者系列)

1. Object wait/notify 原生生产者消费者

基于对象监视器,基础阻塞队列实现,synchronized + wait/notifyAll。
缺点:唤醒无序、存在虚假唤醒,代码繁琐。

2. Lock + Condition 多条件生产者消费者(精准唤醒模型)

ReentrantLock + 两个Condition:notFull、notEmpty

  • 队列满:生产者await(notFull)
  • 队列空:消费者await(notEmpty)
    精准唤醒,避免全量唤醒竞争,高性能阻塞队列底层实现。

3. BlockingQueue 阻塞队列模型(工业级标准)

ArrayBlockingQueue / LinkedBlockingQueue,封装好生产消费逻辑,日常开发最常用。

BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
// 生产者
new Thread(() -> {
    for (int i = 0; i < 20; i++) {
        queue.put(i); // 满则阻塞
    }
}).start();
// 消费者
new Thread(() -> {
    while (true) {
        Integer val = queue.take(); // 空则阻塞
    }
}).start();

变种:

  • DelayQueue:延迟任务调度模型(定时过期任务)
  • PriorityBlockingQueue:优先级任务模型

四、异步任务编排模型(多任务依赖执行)

1. CompletableFuture 链式异步编排(JDK8+)

替代CountDownLatch做多异步任务汇总,支持串行、并行、依赖、异常回调。
适用:多接口并行查询、微服务聚合。

// 并行执行两个任务,全部完成后汇总
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> "查询用户");
CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> "查询订单");
CompletableFuture.allOf(f1, f2).join(); // 等待全部完成
String res = f1.get() + f2.get();

核心API模型:

  • thenApply:串行依赖
  • allOf:等待全部完成(等价双Latch)
  • anyOf:任意一个完成即返回(快速失败)

2. ExecutorService + Future 批量任务收集

老式异步批量处理,submit返回Future,循环get阻塞等待全部完成。
缺点:get阻塞无回调,异常处理繁琐,逐步被CompletableFuture替代。

五、独占/共享锁并发模型(资源读写竞争)

1. ReentrantLock 独占可重入锁模型

互斥访问临界资源,替代synchronized,支持公平/非公平、中断等待、限时等待。

2. ReentrantReadWriteLock 读写分离模型

读共享、写独占:大量读少写场景提升并发性能(缓存、配置查询)

  • readLock().lock():多线程同时读
  • writeLock().lock():写操作阻塞所有读写

3. StampedLock 乐观读锁模型(JDK8)

乐观读无锁,写冲突后升级悲观读,高读极低写场景性能远超读写锁。

六、无锁并发模型(CAS 自旋,无内核阻塞)

1. Atomic 原子类模型(AtomicInteger/LongAdder)

CAS自旋更新,无锁,适合计数、统计、自增。
LongAdder分段原子计数:高并发统计接口请求量,比AtomicInteger性能强十倍。

2. LockSupport 线程精准阻塞唤醒模型

底层AQS基石,park/unpark一对一唤醒,用于自定义锁、阻塞队列、线程池。
区别wait/notify:精准指定线程,不受对象监视器限制。

七、批量分治并行模型(大数据分片处理)

1. Fork/Join 分而治之模型

ForkJoinPool,递归拆分任务,子任务并行,最后合并结果。
适用:大数据遍历、数组求和、文件分片解析、树形递归计算。

class SumTask extends RecursiveTask<Integer> {
    @Override
    protected Integer compute() {
        // 拆分任务fork,合并join
    }
}

八、定时/周期并发模型

ScheduledExecutorService 周期任务模型

固定频率/固定延迟执行定时任务,替代Timer(Timer单线程易雪崩)。

九、特殊业务并发模型

1. 线程本地存储 ThreadLocal 隔离模型

多线程数据隔离,每个线程私有变量,无竞争,用于链路Trace、上下文存储。

2. 分段锁模型(ConcurrentHashMap)

分片锁降低锁竞争,JDK7分段锁、JDK8 CAS+synchronized桶锁,高并发Map读写。

3. 熔断/限流并发模型(Guava RateLimiter)

令牌桶/漏桶限流,平滑突发流量,接口QPS控制。

各模型场景快速对比表

模型 核心工具 核心用途
瞬时并发压测 双CountDownLatch 统一时间点释放所有线程
多线程互相等待 CyclicBarrier/Phaser 分批循环并行计算
并发限流 Semaphore 控制同时运行线程上限
生产消费 BlockingQueue/Condition 任务缓冲、异步解耦
多任务依赖聚合 CompletableFuture 微服务多接口并行查询
读写高并发 ReentrantReadWriteLock 读多写少缓存场景
大数据分片计算 ForkJoinPool 分治递归并行
无锁计数 LongAdder/Atomic 接口统计、计数器
定时任务 ScheduledExecutor 周期异步执行
精准线程唤醒 LockSupport 自定义锁、AQS底层

高频面试重点区分

  1. 双Latch vs CyclicBarrier
    双Latch:主线程控制开关,一次性,适合压测;
    CyclicBarrier:线程互相等待,可循环复用,分阶段计算。
  2. Semaphore vs 读写锁
    Semaphore控制总并发数;读写锁区分读/写权限。
  3. CountDownLatch vs CompletableFuture.allOf
    Latch偏底层线程同步;CompletableFuture支持异步回调、异常处理、任务依赖,业务开发优先用。
  4. LockSupport vs Object.wait
    wait依赖synchronized监视器,随机唤醒;LockSupport直接绑定线程,精准唤醒。

需要我把其中任意一种模型给一份完整可运行 Demo 吗?比如 CompletableFuture 批量异步、ForkJoin 分治、Semaphore 限流。

posted @ 2026-07-25 11:52  七星6609  阅读(14)  评论(0)    收藏  举报