85

Are there multiple instances of servlet class? As I hear "each instance of servlet" Can anybody elaborate on this?

Ashwin
  • 12,691
  • 31
  • 118
  • 190
giri
  • 26,773
  • 63
  • 143
  • 176
  • No! The web container creates only one instance of the servlet at first request only by calling the newInstance() method. – Sonoo Jaiswal May 10 '12 at 18:52

6 Answers6

188

When the Servlet container starts, it:

  1. reads web.xml;
  2. finds the declared Servlets in the classpath; and
  3. loads and instantiates each Servlet only once.

Roughly, like this:

String urlPattern = parseWebXmlAndRetrieveServletUrlPattern();
String servletClass = parseWebXmlAndRetrieveServletClass();
HttpServlet servlet = (HttpServlet) Class.forName(servletClass).newInstance();
servlet.init();
servlets.put(urlPattern, servlet); // Similar to a map interface.

Those Servlets are stored in memory and reused every time the request URL matches the Servlet's associated url-pattern. The servlet container then executes code similar to:

for (Entry<String, HttpServlet> entry : servlets.entrySet()) {
    String urlPattern = entry.getKey();
    HttpServlet servlet = entry.getValue();
    if (request.getRequestURL().matches(urlPattern)) {
        servlet.service(request, response);
        break;
    }
}

The GenericServlet#service() on its turn decides which of the doGet(), doPost(), etc.. to invoke based on HttpServletRequest#getMethod().

You see, the servletcontainer reuses the same servlet instance for every request. In other words: the servlets are shared among every request. That's why it's extremely important to write servlet code the threadsafe manner --which is actually simple: just do not assign request or session scoped data as servlet instance variables, but just as method local variables. E.g.

public class MyServlet extends HttpServlet {

    private Object thisIsNOTThreadSafe;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object thisIsThreadSafe;

        thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
        thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
    } 
}
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 21
    +1. I will just add that if the same servlet class is mapped to two different urls in web.xml, then two instances are created. But the general principle still holds, one instance serves multiple requests. – Yoni Feb 02 '10 at 13:55
  • 1
    @BalusC, just wonder, is there is a way to access the the set of initiated servlets from the web app? – shabunc Mar 21 '12 at 19:03
  • 1
    Does the variable thisIsNOTThreadSafe in the class is shared to different users or is only shared to the different pages of the same user. What I mean is like if I browse this page in my computer and you run in your computer, do we share the same space of thisIsNOTThreadSafe? Thanks. – overshadow Aug 25 '14 at 10:01
  • 1
    Yes, @overshadow, if you mean both clients access the same JVM, then there should be only one servlet, thus the private property `thisIsNOTThreadSafe ` will be shared across sessions. Even if you do log out and log in again. – Ricardo Sep 11 '15 at 19:01
  • 1
    Hello, So my understanding is these servlet instance is store in JVM and when the request come, the servlet container search these instance in JVM. is it correct? – T8Z Oct 22 '15 at 02:03
  • 1
    Does all the above 3 steps runs on containers startup? mean does servlet initialized on the container's startup? then why we use ? – Asif Mushtaq Sep 15 '16 at 05:19
  • @UnKnown: http://stackoverflow.com/q/3106452 – BalusC Sep 15 '16 at 07:10
  • 1
    @AsifMushtaq No, the container does not pre-load servlets on startup. The process is the same, except that it may occur on first-request and not at startup. The `` facility allows you to be clear that certain servlets should load *on startup* and, specifically, in what order you want them to be initialized. – Christopher Schultz Aug 15 '18 at 21:25
32

No, there is only one instance of the servlet which is reused for multiple requests from multiple clients. This leads to two important rules:

  • don't use instance variables in a servlet, except for application-wide values, most often obtained from context parameters.
  • don't make methods synchronized in a servlet

(same goes for servlet filters and jsps)

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • So, for repetitive code, would you suggest to move synchonized methods to simple methods in an external class? – Ommadawn Dec 06 '19 at 20:21
11

According to the Java Servlet Specification Version 3.0 (pp. 6-7), there will be one instance per declaration per JVM, unless the servlet implements SingleThreadModel in which case there may be multiple instances per JVM.

Samuel Edwin Ward
  • 6,526
  • 3
  • 34
  • 62
  • Servlet Specification 3. (page 6-7) Section 2.2.1 Note About The Single Thread Model , Says "The SingleThreadModel Interface is deprecated in this version of the specification." – Reva Dec 22 '15 at 22:35
  • @Reva While that interface is indeed deprecated, it will almost certainly never be removed and containers will support it indefinitely. Once a part of the spec, always a part of the spec. – Christopher Schultz Aug 15 '18 at 21:26
6

Although there are already a few good answers, none of them spoke about a Java web application deployed in a distributed environment. This is a practical scenario where actually multiple instances of a single servlet are created. In a distributed environment you have a cluster of machines to handle the request and the request can go to any of these machines. Each of these machines should be capable to handle the request and hence every machine should have an instance of your MyAwesomeServlet in it's JVM.

So, the correct statement would be there is only one instance per JVM for every servlet, unless it implements SingleThreadModel.

SingleThreadModel in simple words says that you have to have only one thread per instance of Servlet, so basically you need to create one instance per coming request to handle it, which basically kills the whole concept of handling requests in a parallel fashion and isn't considered a good practice as the servlet object creation and initialization takes up time before it's ready to process the request.

Saurabh Patil
  • 4,170
  • 4
  • 32
  • 33
  • If you actually want to be über-pedantic (and it's clear that you *do*), then the uniqueness of a servlet is not per-JVM but per-context. You are free to deploy the same application under multiple context paths (within one or more JVMs) and each of them will have an instance of that servlet. – Christopher Schultz Aug 15 '18 at 21:28
  • @ChristopherSchultz: I didn't quite get that, can you please point me to some material to understand it better? Thanks. – Saurabh Patil Sep 05 '18 at 08:25
  • If MyAwesomeServlet is a part of e.g. an application WAR and you deploy it to two contexts (e.g. `/foo` and `/bar`), then you'll have to copies of the `MyAwesomeServlet` class definition and, indeed, two instances of `MyAwesomeServlet` in memory at the same time. So, there can in fact be more than one instance of the servlet per JVM. Note that the JVM considers these to be separate classes because they were loaded by separate ClassLoaders. A separate ClassLoader is required by the servlet spec, and *conceptual* class = "ClassLoader+Class" in Java in general. – Christopher Schultz Sep 05 '18 at 13:29
5

For those that know real JavaScript (not just a library of it), Servlets can be viewed as function objects. As functional objects, the main task of them is to do something, instead of to store some information in their chests. There is no need to instantiate more than one instance of every such functional object, with the same rationale that Java class methods are shared among all instances of that class.

lcn
  • 2,239
  • 25
  • 41
5

There can not be multiple instances of servlet class. Even when there is one instance of the servlet, it is able to handle multiple requests. So it is wise not to use class level variables.

fastcodejava
  • 39,895
  • 28
  • 133
  • 186