什么是同步执行?
顺序阻塞:必须等待前一个任务完成后才能执行下一个任务
代码直观:代码顺序即执行顺序
资源利用率低:等待期间线程处于阻塞状态
什么是异步执行?
非阻塞:触发任务后立即继续执行后续代码
结果处理:通过回调函数/事件/轮询处理完成结果
高并发:适合 I/O 密集型场景(如网络请求)
一、问题场景:用户注册的性能瓶颈
1.1 典型场景描述
某电商平台用户注册接口需要完成以下操作:
- 写入用户信息到数据库(50ms)
- 发送欢迎邮件(200ms)
- 初始化用户积分(100ms)
- 返回响应给客户端
同步实现痛点:
public void registerSync(User user) {
userRepo.save(user); // 50ms
emailService.send(user); // 200ms
pointsService.init(user); // 100ms
}
总耗时约350ms,用户需等待所有操作完成才能得到响应。
二、核心概念解析
2.1 同步(Synchronous)
- 定义:任务按顺序执行,必须等待当前任务完成才能执行下一个
- 特点:
- 代码顺序即执行顺序
- 线程阻塞等待结果
- 简单易调试
2.2 异步(Asynchronous)
- 定义:任务提交后立即返回,结果通过回调/通知机制获取
- 特点:
- 非阻塞执行
- 提高系统吞吐量
- 需要处理并发复杂性
三、技术原理与实现方案
3.1 Java线程池基础
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(4);
// 提交异步任务
Future<String> future = executor.submit(() -> {
TimeUnit.MILLISECONDS.sleep(200);
return "Result";
});
// 获取结果(阻塞)
String result = future.get();
3.2 Spring异步注解
@Async
public CompletableFuture<Void> asyncSendEmail(User user) {
emailService.send(user);
return CompletableFuture.completedFuture(null);
}
四、实战案例:用户注册优化
4.1 同步实现代码
public class UserServiceSync {
public void register(User user) {
// 1. 保存用户(50ms)
userRepository.save(user);
// 2. 发送邮件(200ms)
emailService.sendWelcomeEmail(user);
// 3. 初始化积分(100ms)
pointsService.init(user);
// 总耗时:350ms
}
}
4.2 异步实现方案
public class UserServiceAsync {
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
public CompletableFuture<Void> registerAsync(User user) {
// 1. 保存用户(同步保证数据一致性)
userRepository.save(user);
// 2. 异步发送邮件
CompletableFuture<Void> emailFuture = CompletableFuture.runAsync(
() -> emailService.sendWelcomeEmail(user),
taskExecutor
);
// 3. 异步初始化积分
CompletableFuture<Void> pointsFuture = CompletableFuture.runAsync(
() -> pointsService.init(user),
taskExecutor
);
// 4. 合并异步结果
return CompletableFuture.allOf(emailFuture, pointsFuture);
}
}
4.3 效果对比
指标 | 同步实现 | 异步实现 |
---|---|---|
响应时间 | 350ms | 50ms |
吞吐量(QPS) | 100 | 800+ |
CPU利用率 | 20% | 60% |
代码复杂度 | 简单 | 中等 |
五、适用场景决策树
六、生产环境注意事项
6.1 异步任务管理
-
线程池配置:根据业务类型设置合理参数
# Spring配置示例 spring: task: execution: pool: core-size: 8 max-size: 16 queue-capacity: 1000
-
错误处理:避免静默失败
emailFuture.exceptionally(ex -> { log.error("邮件发送失败", ex); return null; });
6.2 常见问题解决
- 数据一致性:关键操作保持同步
- 资源泄漏:及时关闭线程池
- 任务堆积:监控队列容量
七、高级模式扩展
7.1 响应式编程(Reactive)
public Mono<User> registerReactive(User user) {
return userRepository.save(user)
.flatMap(savedUser -> emailService.sendReactive(savedUser))
.flatMap(emailResult -> pointsService.initReactive(user));
}
7.2 消息队列解耦
public void registerWithMQ(User user) {
userRepository.save(user);
rabbitTemplate.convertAndSend("user-register", user);
}
八、总结与展望
同步异步选择原则:
- 关键路径用同步(如支付核心流程)
- 非关键路径用异步(如日志记录、消息通知)
- IO密集型优先异步
- CPU密集型谨慎异步
未来趋势:
- 虚拟线程(Project Loom)降低异步复杂度
- AI智能调度优化任务分配
- Serverless架构自动弹性扩缩
掌握同步异步的正确使用姿势,让您的系统性能飞升! 🚀