11

我最近了解到,只需添加注释,我就可以轻松地使任何会话 bean 方法异步。@Asynchronous

例如

@Asynchronous
public Future<String> processPayment(Order order) throws PaymentException {
    ... 
}

我知道 Java EE 7 添加了Concurrency Utilities,但是在 Java EE 6 中,方法的线程池配置在@Asyncronous哪里?有没有办法设置超时?它是一个固定的线程池吗?一个缓存的?它的优先级是什么?它可以在容器中的某个地方配置吗?

4

2 回答 2

3

我认为可以通过从注解@Timeout 的方法调用Future.cancel(boolean)来实现超时。需要保留对 async 方法返回的 Future 的引用,Singleton-ejb 可以用于此。

@Stateless
public class AsyncEjb {

    @Resource
    private SessionContext sessionContext;

    @Asynchronous
    public Future<String> asyncMethod() {

        ...
        //Check if canceled by timer
        if(sessionContext.wasCancelCalled()) {
            ...
        }
        ...

    }
}

@Singleton
public class SingletonEjb {
    @EJB
    AsyncEjb asyncEjb;

    Future<String> theFuture;

    public void asyncMethod() {

        theFuture = asyncEjb.asyncMethod();

        //Create programatic timer
        long duration = 6000;
        Timer timer =
        timerService.createSingleActionTimer(duration, new TimerConfig());

    }

    //Method invoked when timer runs out
    @Timeout
    public void timeout(Timer timer) {
        theFuture.cancel(true);
    }
}

编辑(以下新):

在 glassfish 中,您可以通过在管理控制台中设置以下属性来配置 ejb-pool

  • 初始和最小池大小
  • 最大池大小
  • 池调整数量
  • 池空闲超时

请参阅调整 EJB 池

于 2013-06-19T09:41:52.023 回答
3

尽管我发现的解决方案仅在 Java EE 7/GlassFish 4.1 上进行了测试,但我认为它也应该适用于 GlassFish 3.x。

java.net 上有一个 JIRA条目,其中列出了不同的设置。由于 Oracle 将在该站点上拔掉插头,我将在此处引用相关帖子(添加格式):

配置在 domain.xml 中,例如,

<ejb-container>
  <property name="thread-core-pool-size" value="10"></property>
  <property name="thread-max-pool-size" value="100"></property>
  <property name="thread-queue-capacity" value="20"></property>
  <property name="thread-keep-alive-seconds" value="600"</property>
  <property name="allow-core-thread-timeout" value="false"></property>
  <property name="prestart-all-core-threads" value="false"></property>
</ejb-container>

以上所有属性都是可选的。它们的默认值:

thread-core-pool-size: 16
thread-max-pool-size: 32
thread-queue-capacity: Integer.MAX_VALUE
thread-keep-alive-seconds: 60
allow-core-thread-timeout: false
prestart-all-core-threads: false

通过该线程,我还找到了一篇博客文章,解释了核心和最大池大小的工作原理。引用重点:

过去 SUN 正确声明:“这正是它应该表现的方式。首先线程增长到 coreSize,然后使用队列,然后如果队列填满,则线程数从 coreSize 扩展到 maxSize。因此,如果“您使用无界队列,最后一部分永远不会发生。这在文档中都有描述。如果您想要一个无界队列但更多线程,则增加核心大小。否则请考虑有界队列是否更适合您的需求。”

于 2016-11-09T12:48:36.780 回答