This question already has answers here:
How do servlets work? Instantiation, sessions, shared variables and multithreading
(8 answers)
Closed 6 years ago.
What I know
A web container creates a new thread per request.
What I don't know
Are new servlet objects created per request?
Why I am asking this is to get an idea on how thread synchronization issues can happen if the same servlet object is used for multiple requests.If the web container creates a new servlet object for each new reqest, then I don't see an issue. But if it uses the same servlet object to serve multiple requests, synchronization issues can happen.
How is this handled in a typical java web container?
A web container creates a new thread per request.
No. It reuses a thread from a thread pool.
Are new servlet objects created per request?
No. A servlet is a singleton. Only one instance is created per web app. Your servlet must be thread-safe, since it's called concurrently by several threads. But that' usually easy, because a servlet is typically stateless.
Are new servlet objects created per request ?
By default, Servlet container creates a single servlet instance and will be used to serve all of the requests in a separate thread. So ensure that your servlet class is thread safe (i.e., your servlet class should not hold any stateful data as instance variables, etc..).
Adding to that, Servlet containers create the servlet instance either during the container start-up or upon the first request received.
You can force the container to create the servlet instance by specifying the load-on-startup in web.xml or #WebServlet(urlPatterns="/xyz", loadOnStartup=1)).
It is generally better to load the servlets (unless you have any special requirements) using load-on-startup so that the first request will not hit with the performance.
In general sense servlets are Singletons, however if you map the same servlet class to different URL mappings using different names, you will have that many instances of same servlet.
Mostly servlets are stateless, if you do make them statefull, then be very careful about shared mutability .
Earlier servlet API used to have SingleThreadModel Interface to impose single thread access at one point of time, that way you could serve only one request at a time, However I see this interface is deprecated in recent APIs as it doesn't solve the concurrency issues fully, like static variables etc.
Related
For Spring what if I have two requests that access the singleton bean at the same time? Does one request have to wait until the other to finish. How does Spring container find the singleton bean instance for my requests?
For servlets if I have two requests that access a normal class's normal method(no static no other complex things) at the same time? Does one request have to wait until the other to finish to avoid concurrency (at the same time two request are trying to access the object of the same class). How does web container find the instance for my requests?
For Spring, what if I have two requests that access the singleton bean
at the same time? Does one request have to wait until the other to
finish?
Spring container creates one and only one instance for the singleton bean class (like for Controller, Service class, etc..). In Java, there are several ways that you can create singleton instance for a class safely, you can look here for more on this. Once the singleton instance is created by the Spring container then the web requests will be served using that single instance of the controller/service classes.
Also, there is no problem (i.e., there will not be any waits in between) even if two requests access the singleton bean as they will be served in two separate threads and all you need to ensure is that your controller and service classes (i.e., singleton scoped beans) do not carry/hold any state (i.e., they are stateless) and are thread-safe.
How does Spring container find the singleton bean instance for my
requests?
Spring container creates and then injects the singleton bean instances based upon the configurations that you have provided using the xml or through annotations.
For servlets, if I have two requests that access a normal class's
normal method(no static no other complex things) at the same time?
Does one request have to wait until the other to finish to avoid
concurrency (at the same time two request are trying to access the
object of the same class) ?
No, each request will be handled in a separate thread so one request will not wait for the other request to be served/completed i.e., in other words, the requests will be served/processed parallelly. This is achieved by the Web containers by using/managing the Thread pools.
How does web container find the instance for my requests?
Web container (like Tomcat, etc..) creates and loads all of the servlet classes (like Spring's DispatcherServlet or your own custom servlets) and then once the web request comes from the client (like Browser), it will be handled to the servlet according the url-pattern configured in the web.xml or through annotations.
Probably the stupidest question you have ever heard.
Inside the Web container how more than 1 object of the same class is getting created/managed which has same reference variable... Let me explain with an example.
Inside my controller class I have a code piece
AdminUser adminUser= new AdminUser();
So when 2 Admins signs-in to my web application, there will be 2 Objects of the class AdminUser with same reference variable "adminUser"
How is it possible, is it 2 different threads?
Who is managing this threads, web container?
If so, how web container is doing it, is it wrapping application
code with threadLocal?
If its different threads, to maintain a global object (say a counter
for the admins visit counts), "static" won't suffice... it needs to be
"volatile" instead, correct?
So when 2 Admins signs-in to my web application, there will be 2 Objects of the class AdminUser with same reference variable "adminUser"
No.
If that line of code is in a method, the variable is on the stack, and there can be as many instances as there are concurrent invocations of the method, including recursions and calls by multiple threads.
If it's non-static member initialization code, the variable is in the object, and there are as many instances as there are objects.
If the object is a bean, the number of them depends on the object's scope: if application, one; if session, one per session; if view, one per view; etc.
If it's static member initialization code, it shouldn't be.
How is it possible, is it 2 different threads?
See above.
Who is managing this threads, web container?
Yes, and it is also managing bean instances.
If so, how web container is doing it, is it wrapping application code with threadLocal?
No. See above.
If its different threads, to maintain a global object (say a counter for the admins visit counts), "static" won't suffice... it needs to be "volatile" instead, correct?
No. You can maintain it as an instance member of an application-scoped bean.
You should avoid statics completely in a web-app, apart from constants and caches, which you should also avoid.
Are several factors that influence to answer your questions, the j2ee has own specification that manufacturers must follow, and others, they should simply implement as they wish. Is to give the performance they want, or how they should act in certain moments. A Jboss is certainly different from Apache Tomcat performance issues, which makes it hard to answer your first question. Then answer: "It depends on which vendor you are talking. Specifically what Container?"
It also depends if you implement Enterprise JavaBeans in your code because then probably several Beans (objects) will be started (depending on the container) and each request from a client he might share these Beans or create new ones to account for the competition.
Answering their fourth question, the best method would be a counter through a Singleton Session Bean (EJB implementation), in my opinion. But you could do through a static class, in which all other objects can share, but would have to resolve the competition between objects. EJB resolves this competition for you without you having to waste time with it. is for this and many other things the solution of the EJB
I think if you do not implement EJB, and make a very simple code, for each request that a customer does, an object will be created and destroyed (not really, because its depends the JVM to destroy, garbage colletction, but its inaccessible to you) after sending the response to the client container. But again, depends on how you program, of which container ... I hope I have helped you in your inquiry.
I suggest reading the J2EE specification:
JSR-000342 EE 7 Specification
And a good book to read about EJB's: Enterprise JavaBeans 3.1, 6th Edition
By Andrew Lee Rubinger, Bill Burke
This was the answer that I was looking for. Thanks everyone who answered.
Does application server create new thread for each request from same user?
Web Container (Tomcat) spawns new thread for each request (not really, it uses thread pool for performance reasons).
For any request (doesn't matter who made it) a thread is obtained from the pool, the request is processed then the thread goes back to the pool.
Referring to: Head First Servlets & JSP, page 204, third question:
Q. "The
effect of implementing SingleThreadModel is virtually
the same as synchronizing the service method. Both
can bring a web app to its knees without protecting
the session and context state."
What does this mean: "bring a web app to its knees without protecting the session and context state"? Are they saying that it's not enough thread-safe to implement the SingleThreadModel? Because even though only one thread at a time can be running at one servlet, this doesn't stop other servlets from accessing and mutating the context/session scoped variables? If a Servlet implements the SingleThreadingModel, then why would you need to protect session state? It only allows one thread at a time. Even if you open up a new browser window, the servlet wouldn't allow you to make two requests, I think. Maybe they mean that different Servlets with one thread at a time could still corrupt the context/session state if they don't synchronize on that state?
And why are class (static) variables not thread-safe? Because all threads can access and modify (corrupt) that value?
It's still a little vague to me.
Referring to: Head First Servlets & JSP, page 204, third question:
Q. "The
effect of implementing SingleThreadModel is virtually
the same as synchronizing the service method. Both
can bring a web app to its knees without protecting
the session and context state."
What does this mean: "bring a web app to its knees without protecting the session and context state"? Are they saying that it's not enough thread-safe to implement the SingleThreadModel? Because even though only one thread at a time can be running at one servlet, this doesn't stop other servlets from accessing and mutating the context/session scoped variables?`
This is correct.
If a Servlet implements the SingleThreadingModel, then why would you need to protect session state? It only allows one thread at a time. Even if you open up a new browser window, the servlet wouldn't allow you to make two requests, I think.
That is incorrect. You could have another tab, another window or whatever. You might not be able to access the same Servlet at the same time, because you might be blocked, but you could access another Servlet that also accesses the same Context or Session. And, according to the API, it is allowable to have multiple instances of the same Servlet serve multiple responses in different threads (the only restriction is that one instance can't server multiple threads).
Maybe they mean that different Servlets with one thread at a time could still corrupt the context/session state if they don't synchronize on that state?
And why are class (static) variables not thread-safe? Because all threads can access and modify (corrupt) that value?
There is nothing inherently more or less thread-safe about static variables than instance variables. But you have to understand how the values are protected and how the SingleThreadModel is implemented. If the SingleThreadModel is implemented by allowing multiple instances of the Servlet, each stuck on a single Thread, then the static variables would be shared among all instances and therefore accessible to their threads as well.
Regardless, I would think you should never use (non-final) static variables in the Servlet class because you don't control the Servlet's life cycle. It can be created, destroyed, and recreated as the container demands. So a value you put in the static variables may not be there when you next try to access it. And you should never use the SingleThreadModel because it is inefficient and doesn't really do its job, and it has been deprecated for a long time. So you definitely should not use them both together.
bring a web app to its knees
Because the access to the service() method of the Servlet will be synchronized . This can be implemented in two ways , (1) block other request threads till the current thread completes execution of the service() , (2) Create new instance of the Servlet (or maintain a pool of Servlet instance) in the Container and each request invokes the service() of a separate instance. Both are resource intensive and non performant.
without protecting the session and context state
Because even though you synchronize access to the service() method of your particular Servlet which implements the SingleThreadModel . The access to the session and context are not synchronized . Code other than your Servlet are free to access HttpSession or ServletContext attributes.
Are they saying that it's not enough thread-safe to implement the SingleThreadModel?
Yes , even the class variables may not be thread safe , if the Container implements the model such that each thread uses a free Servlet instance from the pool.
Because even though only one thread at a time can be running at one servlet, this doesn't stop other servlets from accessing and mutating the context/session scoped variables?
Absolutely.
If a Servlet implements the SingleThreadingModel, then why would you need to protect session state?
To protect the data stored in the HttpSession . Because even though only one thread at a time can be running at one servlet, this doesn't stop other servlets from accessing and mutating the context/session scoped variables.
class (static) variables not thread-safe
Because it is shared by all instances of a class.
And why are class (static) variables not thread-safe? Because all
threads can access and modify (corrupt) that value?
Correct. If a member is static, one thread can set a value and another thread can set differently. As static is shared variable, the value set by first thread will be the same for another thread also.
Q. "The effect of implementing SingleThreadModel is virtually the same
as synchronizing the service method. Both can bring a web app to its
knees without protecting the session and context state."
Even if you make some servlet implement SingleThreadModel, it will stop only those thread to executly simultaneoulsy which are trying to access that servlet. It can't stop all other servlets which do not implement SingleThreadModel from accessing context and session attributes. This is because context attributes are available all over the web application and anyone resource can access them and modify them.
I have few questions. As far as I know, every request to a container becomes a HttpServletRequest. More request-> more instances of HttpServletRequest. Then, when a request object calls a servlet called 'abc', an instance of 'abc' servlet is created. Let's say same time 3 requests come to 'abc' servlet ,then
(1) I want to know ,does it mean, 3 instances of 'abc' servlet per each request are created? or requests are queued till one request to the servlet is done.
Then let's say,3 request to 'abc' servlet do some database processes which could be insertions and retrieves at the same time. Then
(2) does one request should be in the queue until other request's servelt completes the task (synchronize)or all servelets do their DB task as multi threads as seperate tasks(not sinchronized) ?
(3). If they work as not synchronized, how can we make those tasks synchronized (lets say, only one particular task-save some thing to DB) and queued ? to do so, is it better to implement the servlet SingleThreadModel or use a method which is in a class created according to singleton pattern ? Then how it affect to the performance of the container?
In short,how can we run a particular task synchronized for all requests ?
I read this as well. That article says about servlets. Lets say the task of a servlet is handed over to another class, then I would like to know how about using singleton pattern on this?
A container may create a pool of servlet instances (an excerpt from a servlet spec below explains the details). It may use three different instances for three concurrent requests or may use one for all three. Your servlets thus need to be thread safe and shouldn't have state in their member variables. The SingleThreadModel marker interface will signal to container not to use same instance of the servlet for more than one concurrent request (thus making your servlet thread-safe) but it won't prevent the container from creating multiple instances and using them simultaneously. makes sense? if your operation requires synchronization then you handle it in your Model classes, not your Controller. So basically synchronize (or queue things up) elsewhere is the answer. Let the servlets take the command and just run with it without putting too much thoughts into the process.
UPDATE. A very basic example of explicit operation synchronization for your case (not that I like it, just to illustrate the point) would be to have a singleton service handling your operation with its main do() method declared as synchronized. Ideally, though, you would delegate database concurrency to your database and persistence layer (transactions, optimistic concurrency).
CORRECTION as per the servlets spec:
In the default case of a servlet not implementing SingleThreadModel and not hosted in a
distributed environment, the servlet container must use only one instance of a servlet class
per servlet definition.
In the case of a servlet that implements the SingleThreadModel interface, the servlet
container may instantiate multiple instances of that servlet so that it can handle a heavy
request load while still serializing requests to a single instance.
With that said, you would have only one instance of your servlet unless you use that single thread model marker.
1) No, only instance of servlet exists per server
2) No, each request is separate thread
Your server could shouldn't contain any instance variables (or) static variables, then synchronization won't be any issue because each thread will have it's own copy of local variables and execution sequence.
3) You can make servlet synchronized by prefixing synchronized the doGet(), doPost() methods are with the help of synch block. But it is bad practice.
Refer this SO Wiki link for complete discussion.
to synchronize a particular task, Let me suggest 2 ways.
use java synchronized block. You should consider what object is suitable for the lock object.
use database lock. Such as select * from xxx for update
Basically, how long is an instance of a servlet around for? I am kind of guessing it is session scope. However, I suppose it could have some sort of timeout or garbage collection to remove old instances.
a servlet is created when the application starts (it is deployed on the servlet container) or when it is first accessed (depending on the load-on-startup setting)
when the servlet is instantiated, the init() method of the servlet is called
then the servlet (its one and only instance) handles all requests (its service() method being called by multiple threads). That's why it is not advisable to have any synchronization in it, and you should avoid instance variables of the servlet
when the application is undeployed (the servlet container stops), the destroy() method is called.
The lifecycle is well defined, and exposed through lifecycle methods exposed in init, service, and destroy methods of the Servlet.
And, despite what else is being said here, this is all you can count on from the specification. Basically, you get those three methods and a guarantee that Servlets are not thread safe. That a single servlet MAY be simultaneously accessed by one or more requests.
There is nothing in the specification that limits a servlet to one instance the container, if a container decides to, it can get a request, create a servlet, call it's init, then service, then destroy methods, and set it free for garbage collection.
Individual containers have potentially different implementations.
Most containers do create a single instance. But the specification does not guarantee that, so you shouldn't rely on it.
Also, consider something like Google App Engine. GAE is VERY aggressive is continually expiring and shutting down entire web apps that receive no traffic. If you have a lightly traveled site, you can very well expect the entire app to start up, init all of its services, init any load-on-startup servlets, execute the request, and then shut everything down. So, on GAE it's imperative that you have a very fast application startup in order to maintain any semblance of performance.
So, simply, what you can count on is what the specification says. Individual containers may offer different run time experiences.
A Servlet lives as long as the application does.
A servlet is not bound to a session, it is a service object that is instantiated by the container when needed, and typically is kept alive for the full life of the webapp. It typically responds to requests from several clients (and sessions), even concurrent requests.
That's precisely why your servlet code must be thread safe, and you never store in a servlet field some data associated to a request or a session.
A servlet life cycle can be defined as the entire process from its creation till the destruction. The following are the paths followed by a servlet
The servlet is initialized by calling the init () method.
The servlet calls service() method to process a client's request.
The servlet is terminated by calling the destroy() method.
Finally, servlet is garbage collected by the garbage collector of the
JVM.
More here ..
http://www.dzone.com/links/r/java_ee_servlets_life_cycle.html
when i remember correctly servlets live as Singletons in the Servlet Container (e.g. Tomcat). Im not sure if the first instantiation is lazy, meaning that the Servlet gets constructed only if needed, but im guessing one could check this in the corresponding Servlet Container's Classloader sources.
The Servlet's lifecycle ends and it's destroy() method gets called when the Servlet Container is shut down.
You can check this easily by setting up breakpoints or logging in the appropriate init() and destroy() methods and Constructor then just check when the code gets executed in your debugger/logfile.
hope that helped.
References:
Tomcat's Classloader howto
The servlet (its one and only instance) will handle n number of request in the fashion of separate single thread for every client ie where CGI limitation is overcomed
A servlet object lives in heap of serverside machine as long as application is undeployed or servletConatiner is shutdown the servlet object will not die.
Technically : servletcontainer holds servletobject and servletobject holds servletConfig object
Servletcontainer can only call the 3 methods of its life cycle 1)init() 2)service() 3)destroy()
Actually the Servlet may be destroyed and recreated at any time ! So the other answers kinda describe the whole lifecycle but miss this important detail. From the servlet specification:
The servlet container is not required to keep a servlet loaded for any particular
period of time. A servlet instance may be kept active in a servlet container for a
period of milliseconds, for the lifetime of the servlet container (which could be a
number of days, months, or years), or any amount of time in between.
[...]
Once the destroy method is called on a servlet instance, the container may not route
other requests to that instance of the servlet. If the container needs to enable the
servlet again, it must do so with a new instance of the servlet’s class.
The lifecycle of a typical servlet running on Tomcat might look something like this:
1.Tomcat receives a request from a client through one of its connectors.
2.Tomcat maps this request to the appropriate Engine for processing. These Engines are contained within other elements, such as Hosts and Servers, which limit the scope of Tomcat's search for the correct Engine.
3.Once the request has been mapped to the appropriate servlet, Tomcat checks to see if that servlet class has been loaded. If it has not, Tomcat compiles the servlet into Java bytecode, which is executable by the JVM, and creates an instance of the servlet.
4.Tomcat initializes the servlet by calling its init method. The servlet includes code that is able to read Tomcat configuration files and act accordingly, as well as declare any resources it might need, so that Tomcat can create them in an orderly, managed fashion.
5.Once the servlet has been initialized, Tomcat can call the servlet's service method to process the request, which will be returned as a response.
6.During the servlet's lifecycle, Tomcat and the servlet can communicate through the use of listener classes, which monitor the servlet for a variety of state changes. Tomcat can retrieve and store these state changes in a variety of ways, and allow other servlets access to them, allowing state to be maintained and accessed by various components of a given context across the span of a single or multiple user sessions. An example of this functionality in action is an e-commerce application that remembers what the user has added to their cart and is able to pass this data to a checkout process.
7.Tomcat calls the servlet's destroy method to smoothly remove the servlet. This action is triggered either by a state change that is being listened for, or by an external command delivered to Tomcat to undeploy the servlet's Context or shut down the server.
Reference:
https://www.mulesoft.com/tcat/tomcat-servlet
life cycle of servlet >
1) load the class.
2) instantiate the servlet.
3) servlet container construct the servlet config interface.
4) container call the init() and pass the servlet config object.
5) httpRequest and httpResponse object created.
6) container call the service() and pass the httpRequest and httpResponse object as argument.
7) process the service method.and if have any other request then follow the step 4 again.
8) other wise container call the distroy().
The servlet's container is attached to a web server that listens for HTTP or HTTPS requests on a certain port number (port 8080 is usually used during development and port 80 in production). When a client (user with a web browser) sends an HTTP request, the servlet container creates new HttpServletRequest and HttpServletResponse objects (for every new request) and passes them through any defined Filter chain and, eventually, the Servlet instance.
In the case of filters, the doFilter() method is invoked. When its code calls chain.doFilter(request, response), the request and response continue on to the next filter, or hit the servlet if there are no remaining filters.
In the case of servlets, the service() method is invoked(by multiple threads for different request). By default, this method determines which one of the doXxx() methods to invoke based off of request.getMethod(). If the determined method is absent from the servlet, then an HTTP 405 error is returned in the response.
The request object provides access to all of the information about the HTTP request, such as its headers and body. The response object provides the ability to control and send the HTTP response the way you want by, for instance, allowing you to set the headers and the body (usually with generated HTML content from a JSP file). When the HTTP response is committed and finished, both the request and response objects are recycled and made for reuse.