7 Replies Latest reply on Oct 1, 2018 11:42 AM by Helen Chen

    how to use ExecutorService in webapp

    Helen Chen Novice

      Hi there,

       

      I have a restful webapp. request can contain large set of data. so inside the restful webservice logic, I want to split the processing into 2 parts. the 1st part will receive data, validate data and save data to database. the 2nd part is really going through the data and apply business logic to it. The 2nd part can take a while to finish. The 1st part does not need to wait for 2nd part output.

       

      so I'm thinking to make 2nd part as Runnable, and to use ExecutorService, like

      `Executors.newCachedThreadPool()`

       

      so I think I can have a singleton to hold this ExecutorService instance, when the 1st part finish, it can submit the job to the ExecutorService, and ExecutorService will execute the 2nd part. This way the ExecutorService will holds a thread pool, the thread can also be reused. So basically I use ExecutorService for background processing

       

      But I'm not sure about a few questions:

      1. is this the right way to use ExecutorService? Is there any better way to do it?

      Since I'm already inside a webapp server (I'm using Wildfly), can I also use ExecutorService like this? Somehow I feel ExecutorService is usually used either on server side or in a standalone application.

       

      2. how and when do I initial the shutdown for the ExecutorService?

      Since I'm making it as Singleton, I expect this ExecutorService instance keeps running until the application is undeployed or the server is shutdown. So when and how the shutdownNow() can be triggered? also when the server is shutdown, even the tasks inside ExecutorService is not done, I guess I have no control on it. Is there anything I can do to at least log something?

       

      Thanks, Helen

        • 1. Re: how to use ExecutorService in webapp
          James Perkins Master

          It's probably best to use the Java EE 7 concurrency utilities which will allow an executor to be injected. For some details see 56 Concurrency Utilities for Java EE (Release 7) . There's also an example in the WildFly quickstarts.

           

          --

          James R. Perkins

          • 3. Re: how to use ExecutorService in webapp
            Helen Chen Novice

            Hi James,

            This quickstarts tutorial set is big. I don't quite get it.

            To use Managed Executor Service, I would like to be able to specify the ThreadFactory (like customize thread priority, thread pool name), and maybe core_pool_size....

            I'm not sure if I need to create my own customized ThreadFactory for configuration. And I don't know how to configure Wildfly for the customized Executor service, and how to specify the Managed Executor service at injection time.

            o you know any example or document that can focus on this area, so I can go through and play with example for understanding?

             

            I'm using Wildfly 10 on Solaris 10.

            Thanks, Helen

            • 4. Re: how to use ExecutorService in webapp
              James Perkins Master

              Hi Helen,

              There is some documentation on how it works in the WildFly documentation. The easiest way to configure it would probably be in the web console. There is a way to configure different thread factories.

               

              If you're interesting in using CLI you can see the model here.

               

              --

              James R. Perkins

              1 of 1 people found this helpful
              • 5. Re: how to use ExecutorService in webapp
                Helen Chen Novice

                Hi James,  thanks for your info. I finally got back to this and I think I made Managed Executor Service work.

                 

                I have some questions raised from load test. the following are what I added to standalone.xml file.

                <managed-thread-factory name="UploadThreadFactory" jndi-name="java:jboss/ee/concurrency/factory/uploadThreadFactory"/>

                <managed-executor-service name="UploadManagedExecutor" Jodi-name="java:jboss/ee/concurrency/executor/uploadManagedExecutor" context-service="default" thread-factory="UploadThreadFactory" hung-task-threshold="60000" core-thread="5" max-thread="100" keep-alive-time="5000" queue-length="500"/>

                 

                when the system is not busy, I don't want to pool to have too many idle threads there, so I set core-thread=5, I'm thinking the rest can be queued up and then processed. But from load test with 50 concurrent user, the throughput is low, like 4.7, meaning there are about 4.7 requests got response.  I think this is because of parameter core-thread set to low.

                 

                but if I set the core-thread  high like 100, then that means when system is not busy, there will be 100 idle threads in the pool.  Is this good? I prefer that when system not busy, the idle  core thread can also be  terminated, this way there won't be too many idle threads staying in the pool.

                 

                ThreadPoolExecutor has a method "allowCoreThreadTimeOut".  I don't see it in Wildly ManagedExecutorService configuration.

                 

                is there anyway I can turn this "allowCoreThreadTimeOut" on? this way I can set core-thread high without worrying too many idle thread in the pool, and also when too many requests coming in, it can handle the requests quicker.

                 

                it is also possible that my understanding for ManagedExecutorService parameters are wrong.  Does anyone have any suggestion how to set parameters to handle both heavy load and light load without too many idle threads left int he pool?

                 

                Does anyone have any suggestion like usually in production environment, what value range should be set for each parameters, like core-thread, max-thread, queue-length, keep-alive-time...

                I actually don't know usually how many threads running in production environment, so I don't know what value range to start to play with parameters.

                 

                Thanks a lot,

                 

                Helen

                • 6. Re: how to use ExecutorService in webapp
                  James Perkins Master

                  Hi Helen,

                  It doesn't look like there is a way to set the allow core thread time out. It looks like the ManagedThreadPoolExecutor has a setThreadLifeTime as well that's not exposed which sets the value to true. This does seem like something reasonable to expose. Feel free to file a JIRA to expose a feature like this.

                   

                  As far as what a good setting is, it just depends. I'm definitely not a pro at tuning

                   

                  --

                  James R. Perkins

                  • 7. Re: how to use ExecutorService in webapp
                    Helen Chen Novice

                    Hi James,

                    Thanks a lot for the documents and help.

                    Helen