JSR 236(Java Specification Request 236)的正式名称是:
Concurrency Utilities for Java™ EE
(Java EE 并发工具)
它于 2013 年作为 Java EE 7 的一部分正式发布 ,旨在将 Java SE 中广受欢迎的并发工具(如 java.util.concurrent 包中的线程池、Future、Executor 等)安全地引入 Java EE 应用服务器环境,同时遵守 Java EE 对资源管理、事务、安全和生命周期的严格约束。
一、为什么需要 JSR 236?
在 Java EE 6 及之前,直接创建线程或使用 java.util.concurrent 是被禁止或不推荐的,原因包括:
- 应用服务器需要管理所有线程 ,以确保:
- 事务上下文正确传播
- 安全凭证(Security Context)可继承
- 类加载器隔离
- 应用停止时能优雅关闭线程
- 开发者若自行
new Thread()或Executors.newFixedThreadPool(),会导致:- 内存泄漏
- 事务失效
- 安全上下文丢失
- 应用无法正常部署/卸载
因此,Java EE 需要一套受容器管理的并发工具------这就是 JSR 236 的使命。
二、核心目标
✅ 提供标准 API,允许 Java EE 应用安全地执行异步、并行任务
✅ 与 Java EE 容器集成:支持 事务、安全、命名上下文、生命周期管理
✅ 兼容 Java SE 的 java.util.concurrent 编程模型,降低学习成本
三、主要组件与 API
JSR 236 定义了以下受管资源(通常通过 JNDI 查找或注入):
| 资源类型 | 接口 | 说明 |
|---|---|---|
| ManagedExecutorService | javax.enterprise.concurrent.ManagedExecutorService |
受管线程池,用于提交 Runnable/Callable |
| ManagedScheduledExecutorService | javax.enterprise.concurrent.ManagedScheduledExecutorService |
支持延迟/周期性任务的受管线程池 |
| ManagedThreadFactory | javax.enterprise.concurrent.ManagedThreadFactory |
创建受管线程(通常由容器内部使用) |
| ContextService | javax.enterprise.concurrent.ContextService |
手动传播上下文(如安全、事务)到异步任务 |
这些接口都位于
javax.enterprise.concurrent包中(注意不是java.util.concurrent)。
四、典型使用方式
1. 通过资源注入使用(推荐)
java
@Stateless
public class OrderProcessingBean {
@Resource
private ManagedExecutorService executor;
public void processOrdersAsync(List<Order> orders) {
for (Order order : orders) {
// 提交异步任务
Future<String> future = executor.submit(() -> {
// 此处运行在容器管理的线程中
// 自动继承调用者的安全上下文、类加载器等
return processOrder(order);
});
}
}
private String processOrder(Order order) { /* ... */ }
}
2. 配置(在 web.xml 或应用服务器中)
xml
<!-- web.xml -->
<resource-ref>
<res-ref-name>concurrent/MyExecutor</res-ref-name>
<res-type>javax.enterprise.concurrent.ManagedExecutorService</res-type>
</resource-ref>
然后通过 @Resource(lookup = "java:comp/env/concurrent/MyExecutor") 注入。
五、关键特性
| 特性 | 说明 |
|---|---|
| 上下文传播(Context Propagation) | 自动将调用线程的 ClassLoader、JNDI 上下文、安全身份(Principal) 传递给异步任务 |
| 事务边界 | 异步任务不会自动加入调用者的事务(避免跨线程事务混乱),但可通过编程方式控制 |
| 生命周期管理 | 应用停止时,容器会等待任务完成或强制中断,防止资源泄漏 |
| 与 EJB、CDI 集成 | 可在 EJB、Servlet、CDI Bean 中安全使用 |
六、与 Java SE ExecutorService 的区别
| 对比项 | Java SE ExecutorService |
JSR 236 ManagedExecutorService |
|---|---|---|
| 线程创建 | 应用自行管理 | 容器管理 |
| 上下文传播 | 无 | 自动传播安全、JNDI、ClassLoader |
| 事务 | 不感知 | 明确隔离(默认不参与调用者事务) |
| 应用停止 | 可能导致线程泄漏 | 容器负责优雅关闭 |
| 可移植性 | 通用 | 仅限 Java EE / Jakarta EE 环境 |
七、现状与演进
- Java EE 7+:JSR 236 成为标准。
- Jakarta EE 8/9/10 :规范迁移至
jakarta.enterprise.concurrent包,功能保持一致。 - Spring 用户注意 :Spring 提供了自己的
@Async和TaskExecutor,不依赖 JSR 236,但在原生 Java EE/Jakarta EE 应用中,JSR 236 是官方标准。
八、总结
| 项目 | 内容 |
|---|---|
| JSR 编号 | 236 |
| 名称 | Concurrency Utilities for Java EE |
| 发布时间 | 2013(Java EE 7) |
| 核心价值 | 在 Java EE 中安全、标准地使用并发 |
| 关键接口 | ManagedExecutorService, ManagedScheduledExecutorService |
| 解决痛点 | 禁止随意创建线程,提供容器管理的异步执行能力 |
💡 记住:在 Java EE / Jakarta EE 应用中,永远不要
new Thread()!使用 JSR 236 提供的受管并发工具。
官方文档(Jakarta EE 版本):
https://jakarta.ee/specifications/concurrency/