I want to guarantee thread safety in one of my Servlet. SingleThreadModel is deprecated and does not guarantee thread safety. Instead of that I can use synchronized block inside my Servlet.

Is thee an alternate way to guarantee thread safety in Servlet?

If Yes, Please explain how can I achieve that.

If no, what will be my design approach to guarantee thread safety in Servlet?

1

There are 1 best solutions below

0
On BEST ANSWER

There is nothing special about a Java Servlet that makes it any more or less susceptible to threading issues, but any threading issues you may have in a Java Servlet quickly become apparent because of the multi-threaded nature of a web server in general.

I'm only saying the above because I want to reinforce the point that Java Servlets are not special. You can easily write any code that isn't thread-safe. It's just much harder to get away with it in a Java Servlet.

One popular technique for building applications is to separate (logically and physically) your code into three piles: the model (your data), the view (UI), and the controller -- usually abbreviated as "MVC". When you do this, you consider the "view" and the "controller" to be stateless. That is, the model contains all of the state of the program/user/transaction/whatever, and the controller and the view simply modify that state as necessary and allow that model to flow through the code.

In a servlet container, the Servlet itself is either the controller (or the view) and should be stateless. That's very easy to do: simply don't use any class members that contain anything that is user- or transaction-specific. Any Servlet class members must be thread-safe themselves (like ConcurrentMap) or be used in a thread-safe way (e.g. synchronized blocks around access to a HashMap). Remember that even a threadsafe collection (e.g. ConcurrentMap) can be used in a non-thread-safe way, like this:

ConcurrentMap cm = ...;
if(!cm.containsKey("foo")) {
    cm.put("foo", createFoo());
}

The above code can't prevent two threads from calling createFoo, which may be an expensive (or destructive!) operation. You need to use a synchronized block to avoid a race condition between two threads.

So, where do you put the model? Well, there are several options you have for this. One of the easiest ways is to keep everything in the user's session. The session is a structure that is user-specific and available to through all HttpServletRequest objects, so it's always available to a servlet. This only works if users actually login to your application, though. Let's assume for now that you do have users and that they have their own sessions.

The session is automatically associated with the request based upon the identity of the user making the request. Any other data you need should come from the request itself (likely, the request parameters that come from the query string).

You can put anything you want into the session. Custom classes that describe your "business objects" (the things you use to represent concepts in your particular application) are preferable to Map objects which contain named collections of other Maps, Listss, etc. I've seen complete web applications built with nothing other than the standard Java library classes and they are a mess of Map-lookups and magic list-indexes. Don't fall into that trap: write your own classes.

Another option for user-model data is to store it in a database of some kind. There are many options for a "database" from simple file-stores to relational databases to document/column/index stores. They all have their own strengths and weaknesses. But they store data, and you can put user-model data into a database. How do you identify the user? Probably by storing a user-id in the session. (So it usually all comes back to sessions). You could also use the user's username (available from the request) to look-up the user's data in the database.

In any case, you should not store anything about the user's state (including workflow, etc.) in the servlet's class members. If you avoid doing that, you are halfway to never worrying about thread-safety in your servlets.

The other issue is that of shared resources. The solution to that problem is to make sure you use those shared-resources in a thread-safe way. That can usually be done with pooled resources such as a connection pool to a database, message queue, search index, etc. Solving those problems is usually very specific to the type of resource being shared, so you might want to ask a more specific question when you get to that stage.