I got some doubts on synchronization concept. whenever i red about synchronization they talk about threads that synchronization makes sure that only single thread will execute some block of code.
my doubt is if i have this synchronized method in web application
public synchronized void counter()
1.now 2 users (not threads) who are being served by 2 different instances of this class, send request to this method ,
so will synchronized method allow only 1 user at a time to access this this increment code?
No. Since the different 'users' are using different instances of the class, they can both execute the code at the same time. That is because the synchronized method locks on the instance itself - thus two different instances means two different locks. If both 'users' are using the same VM, and you DO want to make sure that only one can execute the code at one time, then you need to synchronize on some static object. Typically you use the .class object (but that isn't necessary - it is just a good starting point):
If the 'users' are not using the same JVM, then you need to synchronize on something outside Java - like a DB, File, or Socket.
The code you provided uses all local variables, so there is no real need to synchronize it. I just assume it was a stand-in for real code, though.
1. we can not restrict some code from being executed at same time from different users (say in banking application withdrawal method)?
if we wish to do it we need to do at database level?
That entirely depends on what 'user' means. Without knowing what your application environment and what a user is, then I can't answer that. What I can say - I have said:
1) If the Users use the same JVM - then they can use Java based synchronization
2) If the Users are running code on different JVMs then you need to use external synchronization.
2. in case of servlet 2 users are being served with single instance and 2 threads , code will be executed by one user at a time ?
Again, things get more complicated in an Enterprise environment. Under basic settings - all requests to a servlet would be executed in a single JVM, theoretically using a single servlet instance, and each request on a different Thread. In this case, synchronizing on the instance would be enough to ensure that only one request gets to execute the code at a time.
Warning: This is where I may go into way more info that you need! If this answers your question - feel free to stop now!
But Servlet environments get much more complicated than that very quickly. First - there is no guarantee that there will be just one Servlet instance at a time. The Servlet life cycle is such that you should expect the Servlet to come in and out of service over time. Given that, two users may be using different instances at the same time. So you should synchronize on something other than the Servlet (like perhaps something stored in a ServletContext).
Then there is the concept of load balancing. A single Application may be configured to run on multiple JVMs on the same computer - or use multiple computers, and pass the request to the JVM/server which has the least load. This helps the application scale to many requests. If your environment is set up like this then you can not rely on the Java synchronization scheme - since each server / computer / JVM would have its own instances of the servlets. So in order to protect code from being executed simultaneously by multiple requests which may be being executed on multiple computers, you need to synchronize on some external resource.
I don't think it is un-common for people in JavaEE environments to make there own locking protocol. This becomes relatively easy when you use the Locks which are available in the java.util.concurrent package. You start with Lock implementation that works on a 'simple' environment (perhaps the ReentrantLock already available in java.util.concurrent), and you put it into the ServletContext with a name relative to the data it is supposed to protect. Then the code you want to synchronize you do:
Later, when you get a more complex situation and need to lock across multiple JVMs or application instances you make a different implementation of the Lock interface which uses a database table for locking. The code which uses the "counterLock" doesn't need to change - you only need to change the code which puts the "counterLock" into the ServletContext:
Assuming you wrote an implementation of Lock called DatabaseBasedReentrantLock.