DoGet servlet synchronization - not working?

I know this is a simple question, but somehow I am confused.

If I understand well, in simple words, when a request arrives at a web server, it creates a stream for each request to some servlet.

We believe that we have the following code in MyServlet (I did not consider exception handling, etc.):

synchronized protected void doGet( ... ...){ PrintWritet pw=response.getWriter(); String param=request.getParameter("p"); if(param.equals("a")){ wait(); }else{ notifyAll(); } pw.write("Hello!"); } 

I expect this servlet to get stuck because the first thread (with parameter = a) that goes into this method will wait indefinitely, because any other future thread will get stuck before doGet because of a synchronized keyword, and because of that notifyAll will never be executed.

Now, if I open a new tab in the browser and hit / MyServlet? p = a, browser Waiting for 127.0.0.1 ... After that I open a new tab and hit / MyServlet? P = b (or something that is! = A) The first tab is released and "Hello!" Is printed. message.

This means that the second thread introduced doGet and executed notifyAll.

Why is this happening? What did I miss?

+4
source share
1 answer

Because wait() releases a previously locked lock by introducing a synchronized block. From javadoc for Object.wait :

This thread frees the owner of this monitor and waits until another thread notifies the threads waiting for this object monitor to wake up either through a call to the notification method or the notifyAll method. The thread then waits until it can re-acquire ownership of the monitor and resume execution.

So, your first request gets a lock, enters the doGet method and calls wait (which releases the lock and waits). The second request gets a lock, doGet enters and calls notifyAll , which wakes up the first request stream.

It is very important that you carefully read the documentation for methods such as wait and notify / notifyAll before using them, or if you have problems.

+8
source

All Articles