This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I am having a web application in which in which through a Servlet i run some business logic and then return the acknowledment back.
Now i plan to do this asynchronously so that i would return response as soon as i recieve a request and would run the business logic in a new thread using
So in my servlet i would be doing something like
So there would be a SingleThreadExecutor created per request which i receive. Are there any downside of using this approach and is there any resource cleaning
with respect to SingleThreadExecutor that i need to do explicitely in MyRunnable's run() method.
This would actually be a pretty bad idea, performance wise. Creating a new Executor with every call means you'll be instanciating a new thread every time, and this is fairly expensive. A better way of doing this is using a singleton thread pool - again using the executor class. Using a fixed size or cached executor, you're basically holding a number of threads (deciding on the correct number is critical here) which will be asleep until you submit a Runnable with a job. When a thread finishes with your buisness logic it will return to the pool and can be reused without any (significant) overhead. Idle (sleeping) threads mean very little performance overhead compared to instanciating new ones.
And no, there is no need for any manual resource clearing. However, one important thing to know about Executors: Any Error or Exception thrown in your run method that is not covered by try/catch will not be logged or handled otherwise. Usually, you will obtain a future which you will at some point query for its result, which is when you'll get the Throwable. If, however, you're just asynchronously executing code without a result, make sure you have a try/catch around your entire run method. Better yet, make use of the Thread.setUncaughtExceptionHandler(...) method (see docs for description).
Does that mean i need to have a ServletContextListner in which i would be initializing a thread pool for use by each requester thread at the start of application.
Each thread would then be using an executor provided by the ServletContextListner.
My application is having a user base of around 5000 users so i feel the number of users at peak load would be a contributing factor for the number of threads in cache pool.
Seems to me this would be the best approach. I'd recommend using a thread pool with a fixed size though - you certainly don't want 5000 concurrent threads in your JVM. The number of threads in the pool does not really depend on the number of users, but on the business logic being performed. You want maximum cpu utilization while avoiding unnecessary context switches, which is a target conflict. Basically, you need to consider how much of your business logic is actual work for the cpu. If your Runnables contain pure number crunching, you'll want one thread per cpu (though this is almost ever the case). If you're doing a lot of I/O, you may want 3 or 4 threads per cpu - it is really impossible to determine the best number without inside knowledge and/or profiling of your code.