Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Servlet doGet synchronization - doesn't work?

I know that this is simple question but i'm somehow confused.

If i understand well, in simple words, when request arrive to web server, he creates thread for each request to some servlet.

Consider that we have next code in MyServlet(i left out exception handling and similar):

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 that this servlet will stuck, because first thread (with param=a) that enters this method will hold on wait forever, because any other future thread will stuck in front of doGet because of synchronized keyword, and because of that notifyAll will never get executed.

Now, if i open new tab in browser and hit /MyServlet?p=a, browser Waiting for 127.0.0.1... After that, i open new tab and hit /MyServlet?p=b (or anything that is !=a) first tab is released and print out "Hello!" message.

This means that second thread has entered in doGet, and executed notifyAll.

Why is this happening? What i missed?

like image 686
slomir Avatar asked Feb 24 '23 03:02

slomir


1 Answers

Because wait() releases the lock it previously obtained by entering the synchronized block. From the javadoc for Object.wait:

The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

So your first request obtains the lock, enters the doGet method, and calls wait (which releases the lock and waits). The second request obtains the lock, enters doGet, and calls notifyAll, which wakes up the first request's thread.

It's critical that you read carefully the documentation for methods like wait and notify/notifyAll before you you use them, or you'll get into trouble.

like image 58
skaffman Avatar answered Feb 26 '23 18:02

skaffman