Wednesday, October 1, 2008

Spawn a Thread in a Servlet

When I search this topic on Google, the first impression is that, 'Stop! Just Don't Do It'. Threading code is error prone, not mentioning in a managed container. Additionally there are alternatives like Message Driven Beans or Java Message System, which are specially designed for this purpose. However, you may have a specific situation where threading in Servlet seems to be the only viable solution, for example the JSP page kicks off a long running process at the backend. What can you do? Fortunately it's totally doable if you are careful enough.

First, let's evaluate the risks. Obviously if your servlet is going to spawn multiple threads, this servlet cannot serve many concurrent users at the same time. Otherwise the thread pool will easily dry up and brings the server down to its knees. Concurrent access may cause race conditions and subtle synchronization problems too, especially in a load-balanced or clustered environment. Thread leak may be another risk. If not cleaned up appropriately, each leaked thread will have a reference to its classloader and prevent this classloader from being garbage collected. After enough reload of the application, you may run into out of PermGen space memory errors.

If the risks mentioned above do not apply to your particular situation or didn't scare you off, let's continue. The solution is as the following:
1. Instantiate your thread object as a daemon in your Servlet or ServletContextListener and call yourThread.start();
2. Store it as an attribute in your application context;
3. Return the HttpServletResponse;
4. Clean up the thread when the servlet or the application context is destroyed
5. Don't pass HttpservletRequest/Response/Session objects to the thread