高性能Java并发编程:线程池与异步编程最佳实践

Future模式与CompletableFuture

处理异步任务时,FutureCompletableFuture是强有力的工具。

实战案例:多API并行调用

假设我们需要从多个微服务获取数据,然后合并结果:

java 复制代码
public UserProfileDto getUserProfile(Long userId) {
    long startTime = System.currentTimeMillis();
    
    // 并行获取用户基本信息
    CompletableFuture<UserBasicInfo> basicInfoFuture = CompletableFuture
        .supplyAsync(() -> userService.getBasicInfo(userId));
    
    // 并行获取用户订单信息
    CompletableFuture<List<Order>> ordersFuture = CompletableFuture
        .supplyAsync(() -> orderService.getUserOrders(userId));
    
    // 并行获取用户积分信息
    CompletableFuture<PointsInfo> pointsFuture = CompletableFuture
        .supplyAsync(() -> pointsService.getUserPoints(userId));
    
    // 等待所有任务完成并合并结果
    UserProfileDto result = CompletableFuture
        .allOf(basicInfoFuture, ordersFuture, pointsFuture)
        .thenApply(v -> {
            UserBasicInfo basicInfo = basicInfoFuture.join();
            List<Order> orders = ordersFuture.join();
            PointsInfo points = pointsFuture.join();
            return new UserProfileDto(basicInfo, orders, points);
        })
        .join();
    
    long endTime = System.currentTimeMillis();
    log.info("获取用户档案总耗时: {}ms", (endTime - startTime));
    
    return result;
}

使用CompletableFuture可以将原本串行执行的三个服务调用并行化,显著提升响应速度。

线程池的正确使用姿势

线程池是Java并发编程的重要组件,但使用不当会导致严重问题。

线程池核心参数详解

java 复制代码
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    corePoolSize,      // 核心线程数
    maximumPoolSize,   // 最大线程数
    keepAliveTime,     // 空闲线程存活时间
    timeUnit,          // 时间单位
    workQueue,         // 工作队列
    threadFactory,     // 线程工厂
    rejectedExecutionHandler  // 拒绝策略
);

真实踩坑:线程池参数配置不当

某支付系统中,开发人员使用了这样的线程池:

java 复制代码
// 错误示范
ExecutorService executor = Executors.newFixedThreadPool(10);

在高峰期,系统大量请求堆积,导致内存溢出。原因是newFixedThreadPool使用的是无界队列LinkedBlockingQueue,请求不断堆积最终耗尽内存。

正确的做法是明确指定队列大小,并设置合适的拒绝策略:

java 复制代码
int corePoolSize = 10;
int maximumPoolSize = 20;
long keepAliveTime = 60L;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(1000);
ThreadFactory threadFactory = new CustomThreadFactory("payment-thread-");
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();

ExecutorService executor = new ThreadPoolExecutor(
    corePoolSize, maximumPoolSize, keepAliveTime, unit, 
    workQueue, threadFactory, handler);

这个配置限制了队列大小,并使用CallerRunsPolicy作为拒绝策略,在系统过载时让调用者线程执行任务,起到限流作用。


总结

点赞关注「佩奇的技术笔记」,获取更多并发编程实战技巧!

相关推荐
geovindu9 分钟前
java: Backtracking Algorithm
java·开发语言·windows·后端·算法·回溯算法
NWU_LK13 分钟前
【WebFlux】第六篇 —— 全链路响应式与数据库交互
java·数据库
一只小菜鸡..15 分钟前
南京大学 操作系统 (JYY) 学习笔记:Hello, OS World! (程序的机器视角)
java·笔记·学习
叶总没有会21 分钟前
3.2 构建AI智能体项目扩展知识
java·数据库·人工智能·spring·ai
Lakers-2422 分钟前
1987年6月10日晚上23-24点出生性格、运势和命运
java
唐青枫24 分钟前
Java Jetty 实战详解:从嵌入式 HTTP 服务到 Spring Boot 容器替换
java
腻害兔9 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社10 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖11 小时前
JDK 26 新特性详解
java·开发语言
马优晨11 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎