8

When I read Head First Servlet and JSP, they say that instance variable is non-thread safe.

I don't understand this statement so much. For example: I have a servlet which name is ActionServlet.java. Each time, each user's request is sent to server, container will create a new thread and create new ActionServlet instance.

ActionServlet may be has a structure:

public class ActionServlet extends HttpServlet {
   // example of instance variable
   Instance variable;
   public void processRequest(HttpServletRequest request, HttpServletResponse response) {   
       // process something relating to instance variable
   }
}

So, because all these threads create a new class instance for ActionServlet, so I don't see any problem here. because instances of these thread is separate of each other.

Please figure out where problem when use instance variable in multithread environment.

Thanks :)

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
hqt
  • 29,632
  • 51
  • 171
  • 250
  • 3
    Think about calling the same method on the same object from two threads. – Daniel Fischer Apr 21 '12 at 18:05
  • @DanielFischer I cannot imagine how different thread can use same object because: 1) these variable is private 2)Object of this thread always different from other thread (I think). I have a sample code above. Please tell me more clearer. – hqt Apr 21 '12 at 18:09
  • 2
    @hqt: the container creates a unique instance of the servlet, stores it in some global data structure (a map for example), and each time a request comes in, it gets the appropriate servlet (based on the path of the request) from the map, and calls its service method. The fact that the servlet's fields are private doesn't have any influence. The container doesn't even care about them. – JB Nizet Apr 21 '12 at 18:16
  • @JBNizet Oh, thanks for clear explanation. Your comment bellow still great to me :D I want to have a last question: So, when doesn't have any Thread use that instance of servlet, that instance will be delete out of memory and recreate when need right ? – hqt Apr 21 '12 at 18:19
  • 3
    The servlet is not stored in a thread pool. Threads are stored in a thread pool. The servlet is created at deployment time or when needed for the first time, and then stays in memory until the application is undeployed. If it was removed from memory, the container would have to recreate an instance when a new request comes in, and would thus violate the spec. And there is no good reason to remove it from memory anyway, since a servlet is typically stateless, and thus doesn't consume much memory at all. – JB Nizet Apr 21 '12 at 18:23
  • Do you know if this is true for service/component classes wired in Spring? – IcedDante Jun 24 '14 at 14:46

3 Answers3

19

The mistake you are making is here:

So, because all these threads create a new class instance for ActionServlet, so I don't see any problem here. because instances of these thread is separate of each other.

The container does not create a new instance of the Servlet class for each request. It reuses an existing one. This is why they are not thread safe.

The Stripes Action Framework DOES create a new instance for each request, so that's an okay assumption under that framework. However, for example, Struts 1 follows the Servlet model and does not create a new action per request.

That does not mean that the container is limited to a single instance, it in theory can create more than one, but it's not a specified behavior so can not be relied upon. Most of the popular ones do not.

hqt
  • 29,632
  • 51
  • 171
  • 250
Will Hartung
  • 115,893
  • 19
  • 128
  • 203
  • 4
    In fact, the container MUST create only one instance. Here's what the specification says: "For a servlet not hosted in a distributed environment (the default), the servlet container must use only one instance per servlet declaration" – JB Nizet Apr 21 '12 at 18:13
  • Oh. Thanks for both @JBNizet and Will Hartung. this book doesn't show me that container just ONLY create one instance for one servlet. – hqt Apr 21 '12 at 18:17
3

because all these threads create a new class instance (action.java), so I don't see any problem

You are supposing that every thread create a class instance that will be used only by that thread, that's why you don't have any problem.

But try to imagine, with your specific sample, that the same instance is accessed from two threads. What's happend if both use in the same time your request and response members? Maybe you will read data from unidentifiable request, and you will write an inconsistent response that mix two parts.

So in you case too, instance variable are not thread safe, because if two thread access the same instance they can disturb each other.

dash1e
  • 7,677
  • 1
  • 30
  • 35
0

The thing is, your action.java isn't instantiated always but it is being taken from an instance pool, the same goes for the request threads, they are been taken from a thread pool, so a servlet instance may be shared by multiple requests.

  • 4
    There is no instance pool for servlet. There is only one servlet instance per servlet declaration. – JB Nizet Apr 21 '12 at 18:13