Where can I configure the thread pool behind the @Asynchronous calls in Java EE 6?

前端 未结 2 1402
后悔当初
后悔当初 2021-02-05 23:45

I recently learned that I can easily make any session bean method Asynchronous by simply adding the @Asynchronous annotation.

E.g.

@Asynch         


        
相关标签:
2条回答
  • 2021-02-06 00:20

    Even though the solution I found was tested only on Java EE 7/GlassFish 4.1, I think that it should work for GlassFish 3.x too.

    There's a JIRA entry on java.net where the different settings are listed. As Oracle is going to pull the plug on that site, I'll quote the relevant post here (formatting added):

    The configuration is in domain.xml, for example,

    <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>
    

    All of the above properties are optional. Their default values:

    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
    

    Via that thread, I also found a blog post that explains how the core and max pool size work. Quote of the important point:

    In the past SUN declared correctly: "That is exactly how it is supposed to behave. First the threads grow to coreSize, then the queue is used, then if the queue fills up then the number of threads expands from coreSize to maxSize. Hence if you use an unbounded queue the last part never happens. This is all described in the documentation. If you want an unbounded queue but more threads then increase the core size. Otherwise consider whether a bounded queue is more suitable to your needs."

    0 讨论(0)
  • 2021-02-06 00:32

    I think timeout could be achieved by invoking Future.cancel(boolean) from a method annotated @Timeout. Requires keeping a reference to the Future returned by the async method, Singleton-ejb can be used for this.

    @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);
        }
    }
    

    Edit (new below):

    In glassfish you may configure the ejb-pool by seting below attributes in the admin console

    • Initial and Minimum Pool Size
    • Maximum Pool Size
    • Pool Resize Quantity
    • Pool Idle Timeout

    see Tuning the EJB Pool

    0 讨论(0)
提交回复
热议问题