Why shouldn't we make the service() method synchronized?
[Full question: When we implement singlethreadmodel it means that only one thread can access the service method at a time.now my question is ,why can't we achieve the same thing my making the service() method synchronized. theory says that we shouldn't synchronize the service method. but what will happen if we do so,except from the performance problem?]
service(...)(or any of the
doXXX(...)methods or any method you call from any of these methods). Once you deploy the servlet, the servlet container receives ten "near-simultaneous" requests for the servlet. Upon receipt of the first request, the servlet container kicks off a thread and sends it on its way (i.e. starts it executing the
Unbeknownst to the servlet container, the thread executing in the
service(...) method "locks the door" behind it (holds the lock for the servlet object). Not knowing any better, the servlet container starts the other nine threads and assumes they are happily executing the
service(...) method. In reality, each of the nine other threads finds the object (the servlet instance) locked, so they go into a "wait" state.
Meanwhile, the first thread finishes executing the
service(...) method, so it releases the lock on the servlet instance. One of the other threads--not necessarily the second thread, so we'll say the eighth thread--awakens to find the servlet's lock available, so it requests the lock and starts processing the
service(...) method. Meanwhile, the servlet container may be receiving other requests. It's possible that when the eighth thread (which was the second to execute the
service(...) method) finishes, the thirty-fifth thread grabs the lock.
With this approach each thread has an "equal" probability of being the next allowed to execute the
service(...) method. It's complete anarchy--every thread for itself. About this time, the person who sent the second request is calling you to say that your application is down. :) And, if you really want things to get complex, try synchronizing the
service(...) method and the
So what does the servlet container do? It provides queueing and prioritization (generally first-in-first-out) of requests.
Some servlet containers instantiate multiple servlet objects (and maintain a servlet pool--remember that synchronizing a method locks the object (or instance), not the method, so multiple threads can execute the same method in different instances) to handle multiple simultaneous requests. (Note that this means that you may need to synchronize access of static members.)
Others (like Tomcat, IIRC) provide as little support for
SingleThreadModel servlets as is required by the servlet specification (they don't waste time creating object pools) since using
SingleThreadModel is a "cop out." Keep reading, I'll explain why... :) Implementing the interface often gives developers a false sense of security when it comes to multi-threaded programming. For example, regardless of whether your servlet implements
SingleThreadModel or not, you still need to consider synchronization problems with static members,
ServletContext attributes, and any other classes outside the scope of the servlet (i.e. JavaBeans, support classes, etc.).
So, what do you do if you're not sure whether your servlet is thread-safe? Your best bet is to talk with other developers who have more experience in multi-threaded programming (someone who's been doing it for 30 years is a good beginner ;). Also, do all you can to learn about the topic. IBM's DeveloperWorks website has a lot of articles on multi-threaded programming, including Understand that for instance methods, synchronized locks obj..., Threading lightly, Part 1: Synchronization is not the enemy (and parts 2 and 3), and many, many more. Also, check out some of their tutorials, like Introduction to Java threads.
Best of luck, and have fun with threads.