As it is known, that Servlets use individual threads for the respective requests and this improves the efficiency of server.
Whereas, in the struts2 framework, each mapped Action-Class has its own object been created for the respective requests.
Now, how is it a good practice(optimised) in struts2 to have individual objects as compared to just threads in ordinary servlets ? Why don't we just have servlets !?
When a request comes in to a web container, the container takes a thread from a pool in order to execute the request. Once the request is handled, the thread goes back to the pool to be usable for subsequent requests. Several requests can be handled in parallel, because the pool has several threads available.
Each servlet you declare in your web app is instantiated only once by the web container. A single instance of each servlet is thus used by several concurrent threads. This is why your servlets must be thread-safe.
Struts doesn't change anything to the above. What it does is that it defines a single servlet or filter that handles all the requests. And for each request targeting the path of a given action, a new Struts Action instance is created. This is where the model with servlets differ. A servlet is a singleton (only one instance for all the requests), whereas a new Struts action is instantiated for every request.
The advantage is that the action doesn't need to be thread-safe, since it's used by onlyu one thread and is then discarded. It can contain intermediary state without any need for synchronization. The downside is that many instances are created. But since the Java garbage collector is very fast at recycling short-lived objects like Struts actions, it doesn't cause any problem in practice.
Related
For servlets not implementing the SingleThreadModel interface, if the
service method has been defined with the synchronized keyword, the servlet container cannot use the instance pool approach (excerpt from Java™ Servlet Specification Version 2.5)
So, it's not SingleThreadModel, but specification say about instance pool approach? Normally, if we dont't describe the servlet for SingleThreadModel, only one instance would be created. I'm confused.
The sentence you quoted is not quite clear, but in my interpretation it wants to say the following:
If a Servlet does not implement SingleThreadModel but has a synchronized service method (or synchronized HttpServlet#doGet etc. methods) then the servlet container will not use a instance pool for the servlet.
The requests will simply be serialized through thread synchronization and performance will be bad for concurrent requests.
You need to read the whole of §2.3.3.1 Multithreading Issues in the servlet specification (which has been there since at least Servlet 2.2, and probably earlier) to get the complete context of this sentence.
A container may choose to create a pool of servlet instances that have implemented javax.servlet.SingleThreadModel in order to improve concurrency. Then each thread handling a request directed to this servlet can execute it's own servlet instance (possibly acquired from a pool) instead of blocking until an earlier request has been completed.
The container will not use this mechanism if the developer simply chooses to synchronize the service or related method.
To answer your question explicitly:
an instance pool will never be used for servlets that do not implement SingleThreadModel. Therefore these types of servlet will always be a singleton.
It's all moot though because SingleThreadModel has been deprecated since Servlet 2.4.
What does someone mean when I am asked that whether my web application is thread safe or not , considering that I have not used Multiple threads in my webapplication.
In a normal web-application Servlet treats as Singleton class, it means if you are using instance variable in Servlet that is not thread safe in that case it will create an issue for multiple request that is served simultaneously.
A Java servlet container / web server is typically multithreaded. That means, that multiple requests to the same servlet may be executed at the same time. Therefore, you need to take concurrency into consideration when you implement your servlet.
Read more...
What does someone mean when I am asked that whether my web application is thread safe or not
You have to make sure that all the Servlet/JSP are thread-safe. Do it for all server side classes that is treated as Singleton.
I have not used Multiple threads in my webapplication.
Container/web server starts a new thread for each request.
The servlet specification requires a web application to be thread safe, because the servlet container may (and usually does) process requests concurrently. That is, even if you do not start any threads of your own, the servlet container will, and you must ensure your code is still correct in that case.
That involves protecting any objects shared by several threads (such as the contents of the HttpSession, or any singleton objects) from concurrent access.
An excellent answer to a similar question is witten by BalusC here. Also have a look at Tomasz's answer
Generally, instance variables or state can be shared across threads (threads created by application or the container). So any class(object) that exposes its state for modification, can be considered unsafe. So if your service layer calls some data access object method and the dao is an instance variable inside the service class, the question to ask is this - can this dao or the state of that dao itself be changed by some other client?
You can make your objects immutable. Your custom objects, dates and collections can be mutable. Some of the examples where even getter methods can be dangerous are collections, dates, etc. Use something like ConcurrentHashMap or return a list something like Collections.unmodifiablelist
Another example, instead of returning this.someDate, you should write
public Date getSomeDate() {
return new Date(someDate.getTime());
}
This way some other thread (which may have been spawned by container for another request from another user) holding a reference to the variable someDate will not be able to mess up with this thread.
If you cannot make the state of an object immutable because you want to allow its clients to change its state, you can make all the clients of that object agree to share the state. So if one thread changes the state of a shared object and another thread is ok with the state changed by the first thread, then such monostate object can be ok to have in your application.
As other answers have mentioned the container spawns threads even if your application does not. I have focused here mainly on the topics not directly covered in the answers here so as to avoid duplication. Hope this helps.
Is it possible, that a session-scoped backing bean is accessed by multiple threads at the same time?
The servlet spec says, it is possible:
Multiple servlets executing request threads may have active access to the same
session object at the same time. The container must ensure that manipulation of
internal data structures representing the session attributes is performed in a thread
safe manner. The Developer has the responsibility for thread safe access to the
attribute objects themselves. This will protect the attribute collection inside the
HttpSession object from concurrent access, eliminating the opportunity for an
application to cause that collection to become corrupted.
However I could not make the server (JBoss) use different threads for the same session. When I opened multiple tabs and started a long running request in one tab, and then started a request in another tab, the second tab had to wait for a response until the action started in the first tab was completed.
I also verified this by blocking the thread with a breakpoint in the backing bean. It was not possible to do anything in other tabs of the same session until I resumed the thread.
Despite this we have some strange exceptions in the production log and so far the only possible explanation we have is, that multiple threads concurrently access the same session-scoped backing bean.
Yes, A Servlet session is thread safe. But, if you are putting mutable object in the session. The application should take care of the synchronization.
In your case, if your Bean is Mutable i.e, has state. Yes it has to be thread safe.
And about your test case, it depends on the browser you are using. Most browsers support upto 6 connections in parallel for every server. But, Not sure if they use parallel connections if there have cookies.
How the servlets are shared among every request? I understand that each httprequest are allocated to different thread. How about concurrent request?
When you create your servlet you decide whether you will make it single threaded or multi-threaded. You can mark your servlet as single-threaded by implementing the interface
javax.servlet.SingleThreadModel
See this
A single threaded servlet can serve only one request at a time, and that's usually not what we want. So typically we allow our servlets to be multi-threaded and implement accordingly. Code on the assumption that many threads, each of which corresponds to one user's request, may be in our servlet at the same time. This is not hard to do - avoid using instance variables that can be changed by any one request thread and remember that any synchronized code will become a point of contention.
When a Servlet is requested for the first time or when the webapp starts up, the servlet container will create an instance of it and keep it in memory during webapp's lifetime. The same instance will be reused for every incoming request whose URL matches the servlet's URL pattern.
A separate thread is created to handle each HttpServlet Request.
See Servlet Tag Info for details.The info has links to great resources that would give you a better understanding of servlets.
I understand that each httprequest are allocat[ed] to different thread.
Correct.
How about concurrent request?
They are allocated to different threads.
I knew only one servlet instance (One instance for one servlet basis) will be avilable in the web container. Is it possible to make a pool of instance in the web container ? Like a database connection? If i make a pool of servlet instance then how i can make that as a thread safe? (But i studied we can make only one servlet instance per servlet).
I understand that it was an interview question. I would have answered it as follows:
You can let the servlet implement SingleThreadModel to get the container to create a pool of multiple instances of the same servlet class. The maximum pool size depends on the container used, on Tomcat for example, this is 20. But, a big but, this interface is deprecated since Servlet 2.4! We should actually be writing servlets in a thread-safe manner, without assigning request- and/or session scoped data as an instance variable of the servlet. This way it's safe to use a single servlet instance across multiple threads (read: across multiple HTTP requests).
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
Question is, why would you want to do that?
Servlet container instantiates single instance for each servlet declaration. That means, that you can have multiple servlet instances, but you need to declare the servlet as many times as many instances you want/need. This also brings the question of how servlets would be invoked ... they would need to be mapped to different paths.
Another way you can do this is to make a pool of handlers which your single servlet may call.
Re how to make them thread-safe: that depends on what exactly you want to do in those handlers. It's hard to tell you in general.
If you're asking about thread-safe pool, you can use Apache Commons Pool library, or some BlockingQueue (e.g. LinkedBlockingQueue) in Java: queue may contain your handlers. Servlet will take() first handler, use it, and put() it back after it's done. (This is just an example of course, there are many ways to implement pool).
But ... make sure you really need design like this, maybe your requirements can be satisfied by something simpler? (If your goal is to limit number of concurrent requests handled at the same time, maybe it's enough to just limit number of HTTP worker threads in your container? Or if that's not enough, you can use a limiting filter?)
Defining a pool of servlets does not make sense as the Servlet itself is not a thread. The Web Container (e.g. Tomcat) maintains a thread pool which calls the Servlet instance. So if you want to increase the throughput (concurrent users) you have to increase your web containers' pool size.