DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=3884>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=3884 SingleThreadModel servlets not pooled results in low performance ------- Additional Comments From [EMAIL PROTECTED] 2001-10-02 08:50 ------- NOTE: Tomcat 4 *does* obey the spec requirements related to SingleThreadModel (only one request at a time per instance). It just does not pool them. ============================================================================== The "promise" of SingleThreadModel, especially if you are a new developer that is unfamiliar with multithread environments, is that you don't have to worry about threads at all. But this is completely untrue if your application uses sessions - it is still very easy to have multiple threads talking to the same session at the same time. Consider some of the ways that this can happen: * UI with multiple frames (the browser will make simultaneous requests). * UI with dynamically created images (simultaneous requests for the same reason that frames cause them). * User starts a long transaction, presses STOP, then goes somewhere else. In each case, the expectation that the developer doesn't have to worry about threads is not met. If they don't synchronize use of their session attribute variables appropriately, they are still going to have problems. Ironically, pooling of SingleThreadModel instances (if it were implemented) also violates another expectation that developers are used to in non-STM servlets - that there is only one instance of a particular servlet per <servlet> definition. In web apps, it is common to use instance variables to share application-wide things (like connection pools and hit counters) across all users of that servlet. But this doesn't work in an STM servlet that really is pooled. Further, good multithreading design patterns encourage you to minimize the need for locking (typically implemented with synchronization in Java) - and, when you do lock, you should lock on the smallest unit that is possible. Locking the entire service() method, which is what STM does, is far too heavyweight. An example of this comes from the implementation (inside Tomcat) of the HttpSession interface, where you have methods like getAttribute() and setAttribute() that need to lock the internal HashMap containing those attributes. However, instead of synchronizing on the entire session object (which is similar to what STM does on the entire servlet), the internal code locks *only* on the attributes collection: public void setAttribute(String name, Object value) { ... synchronized (attributes) { ... attributes.put(name, value); ... } ... } so that no other calls to the session that are happening at the same time from other threads (like getId() or setMaxInactiveInterval()) are affected by these locks. This approach maximizes the concurrency - and applications should use similar design patterns for similar reasons. Otherwise, you are needlessly slowing down your application even if pools of STM servlets are available. Finally, there don't seem to be any compelling use cases for SingleThreadModel that cannot be solved using multithread design techniques -- usually, the only thing you need to do is utilize local variables instead of instance variables for per-request state information. So why go to the effort of teaching people two design patterns instead of one? I've followed mailing lists like TOMCAT-USER and SERVLET-INTEREST for several years, and I have seen far too many developers code themselves into corners based on mistaken assumptions about how SingleThreadModel works. I'd rather not encourage it - but if someone wants to propose a patch to enable this, that's OK too (as long as it complies with the spec requirements).