CDI 2.0:如何检查 Event.fireAsync() 可以同时 运行 触发多少个异步事件

CDI 2.0: How to check how many asynchronous events fired with Event.fireAsync() can run simultaneously

我正在使用 Jersey、CDI 2.0(Weld 3.0.1.final 实现)和 Tomcat 编写 REST Web 服务。 Web 服务的目标是启动可以 运行 几分钟甚至几小时的长计算任务。任务应该从发送到 web 服务的 HTTP POST 请求开始,但是请求必须立即完成并将响应发送回客户端,而启动的任务应该在另一个线程上完成它的工作。

我已经使用 CDI 2.0 及其允许异步处理事件的 Event.fireAsync() 方法解决了这个问题。处理 POST 请求的 JAX-RS 资源 class 触发异步事件,然后在单独的 @ApplicationScoped CDI bean 中由异步观察器方法(用 @ObservesAsync 注释)处理。

所描述的解决方案效果很好。但是,我注意到,当我在异步事件中同时触发多个长任务时,实际上只有四个是 运行,而其余的则在排队。一旦四个 运行 事件中的一个完成,第一个排队的事件就会开始处理。

所以,我的问题是:

  1. 如何查看有多少线程可用于CDI事件的真正异步处理?
  2. 如何在异步观察者方法中查看有多少事件排队等待处理?

对于您的第一个问题 - 默认值将基于可用的处理器。类似于 Runtime.getRuntime().availableProcessors() + 1 的内容。 但是,我想您所追求的是配置选项。在这里你可以选择,你可以:

  • 使用焊接配置并从预定义选项中选择
    • 看看configuration part of Weld doc
    • 我建议使用 FIXED_TIMEOUT 池(线程不会在不需要时逗留),此配置的关键是 org.jboss.weld.executor.threadPoolType
    • 您可以使用键 org.jboss.weld.executor.threadPoolSize
    • 设置所需的线程数量
    • 检查 chapter 19.1 如何将配置选项传递给 Weld
  • 定义您自己的 Executor 并使用 NotificationOptions
  • 触发异步事件
  • (OVERKILL) 实现您自己的 ExecutorServices,Weld SPI 的一部分

关于你的第二个问题 - 我不得不让你失望了。目前还没有办法在 Weld 中实现这一点。随意 create a WELD Jira issue 以后你可能会看到它。