|
Introduction
| Servlets
& HTTP | Life-Cycle | Sessions
| Summary
| Examples Life Cycle: Loading | Servicing Requests | Threading | Reloading | ||
Servlet Threading ModelsSingle Thread ModelThe recommended and default use of servlets, is that they be accessed concurrently. That is one servlet instance, running in a multi-threaded environment, taking the required steps to synchronize access to shared resources and ensuring that the servlet is thread-safe. However, a developer can state that requests to a servlet instance be serialised thereby making the servlet run within a single threaded environment. By implementing the SingleThreadModel interface, developers can force a servlet to run single-threaded manner. SingleThreadModel is an empty interface that is used as a marker by servlets wanting to be run a single-threaded manner. According to the specification, "the servlet programmer is guaranteed that no two threads will execute concurrently the service method of that servlet".
Single Thread Model But how can servlets in the SingleThreadModel scale under heavy request loads? From the above figure, we see that the servlet engine maintains a pool of servlet instances for each servlet that implements the SingleThreadModel. When an incoming service request arrives at the servlet engine, it is dispatched to a free servlet from within the pool. It is important to realise that although the servlet instance is thread-safe in the SingleThreadModel (ie. no need to synchronize access to instance variables), the servlet instance still needs to synchronize access to other shared resources. For shared objects such as HttpSession, that are accessible by multiple servlets, you must still program your SingleThreadModel servlet instance to safely access their contents in a multi-threaded environment. When should you implement the SingleThreadModel in your servlets? There is no reason to implement the SingleThreadModel apart from trying to simplify your code by removing the need for synchronization blocks around accesses to the servlet instance variables. However, by single threading service requests to your servlets, you lose out on one of the primary benefits of servlets: high performance within a multi-threaded environment. As a guideline, do not restrict the performance of your servlets by implementing the SingleThreadModel. Instead make your servlets thread-safe. Creating Secondary ThreadsAny servlet can create a thread during its life-time. Because when your inside a servlet you have full power of the JVM at your fingertips. However, with the creation of threads also comes the responsibility of carrying out its timely destruction. In the servlet model, the destroy() callback provides a useful place for checking and removing secondary threads created by your servlets. Why would you need to create secondary threads in the first place anyway? Consider a servlet that needs to display football statistics for all games played today in (sort of) real-time. The football statistics are being feed into a database by another process and the servlet reads these results and presents them to its browser clients. One solution would be for the servlet to open a dedicated connection to the database, read the football data in, turn the data into information, and then generate the required HTML. One issue with this scenario is that for each servlet request, a synchronized database read is needed and the return data needs to be validated and processed before it can be used. An alternative approach would be to create a secondary thread. This thread would be responsible for periodically reading the football results from the database and performing the required data validation and processing. When an HTTP request comes in for todays football results, the servlet queries the secondary thread for its statistics and sends them back to the client. The secondary thread does the work and the servlet deals with the presentating the information as HTML to its clients. When do you create secondary threads? You can create them either in the init() method or during service() requests. But either way you need to maintain a handle on that thread, most likely as instance variables, or possibly as a shared resource (we talk about shared resources in the servlet session section). Destroying a thread can again be done within the service() request based upon some application-specific conditions, or within the destroy() method. It is important that no threads are missed and all those created by a servlet are stopped. Otherwise the JVM will have an orphaned thread that is using up valuable CPU cycles. Also, if the servlet is reloaded, even more orphaned threads will result. In short, if you create secondary threads, make damned sure you model their life-time just as carefully as you model the lifetime of your servlets. Finally, it is important that the servlet developer be aware that both the request (HTTPServletRequest) and response (HTTPServletResponse) objects, according to the specification, "are not guaranteed to be thread safe". So in our example, references to the HTTPServletRequest and HTTPServletResponse should not be passed to objects executing within our statistics gathering secondary thread as the behaviour may be non-deterministic. As the servlet specification warns, request and response objects, "should only be used in the scope of the request handling thread". | |||
(c) Zameer's Online Education 2006 |