tomcat 6 thread pool for asynchronous processing
java, multithreading, threadpool, tomcat
Solution
Answering your short question:
In JVM thread pools are abstracted behind `java.util.concurrent.ExecutorService` interface. There are different implementations of this interface but in most cases methods of this interface would suffice.
To create specific thread pool, take a look at `java.util.concurrent.Executors` class: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html which contains static factory methods for creating different implementations of `ExecutorService` interface. You may be interested in `newFixedThreadPool(int threadsNumber)` and `newCachedThreadPool` methods.
For more general information on `Executors` in JVM you may want to read following Oracle's tutorial: http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html
So, to use thread pool (`ExecutorService`) under Tomcat you should do the following:
.1. Create and register in `web.xml` instance of `javax.servlet.ServletContextListener` interface (which would act like an entry point to your webapplication) if it's not done yet.
.2. In `contextInitialized(ServletContextEvent)` method, you create instance of `ExecutorService` (thread pool) and store it in `ServletContext` attribute map, so that it can be accessed from any point in you webapp e.g.:
// following method is invoked one time, when you web application starts (is deployed)
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
// ...
final int numberOfThreads = ...;
final ExecutorService threadPool = Executors.newFixedThreadPool(numberOfThreads); // starts thread pool
final ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.setAttribute("threadPoolAlias", threadPool);
// ...
}
// following method is invoked one time when your web application stops (is undeployed)
public void contextDestroyed(ServletContextEvent servletContextEvent) {
// following code is just to free resources occupied by thread pool when web application is undeployed
final ExecutorService threadPool = (ExecutorService) servletContextEvent.getServletContext().getAttribute("threadPoolAlias");
threadPool.shutdown();
}
.3. Somewhere in `Servlet.service` method or anywhere in your webapp (you should be able to obtain reference to `ServletContext` almost anywhere from webapp):
Callable<ResultOfMyTask> callable = new Callable<ResultOfMyTask>() {
public ResultOfMyTask call() {
// here goes your task code which is to be invoked by thread pool
}
};
final ServletContext servletContext = ...;
final ExecutorService threadPool = (ExecutorService) servletContext.getAttribute("threadPoolAlias");
final Future<ResultOfMyTask> myTask = threadPool.submit(callable);;
You should store reference to myTask and can query it from other threads to find out whether it's finished and what is the result.
Hope this helps...
Problem
Short question: Within a Tomcat 6 app - how can I run a (separate) thread-pool? What is the best solution for running a thread pool? Long question: I have a simple need here; Poll a database for some data, while allowing web clients wait for an answer (long poll connections). When this data is available at the database I'll send a reply to the relevant client. Saying so, I prefer not to dive into any framework at the moment (`quartz scheduler` maybe?). Therefore, as I conclude, I'll need a thread pool to do the job in the background. So if `Thread` is what I'm about to use (actually `Runnable`), which class can organizes it all? Is there sort of a `ThreadPool` solution? Any recommendation?