• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Servlets: synchronized vs non-synchronized methods

 
Sky Loi
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am testing the servlet application using tomcat and customized multithreded test clients. I try the following different scenarios - synchronize or not the servlet method. In client side, I generate 200 concurrent requests to this servlet. There are quite different CPU usage in this scenarios: non-synchronized one use much more CPU (almost 100%) than synchronized (as usual). Could anyone advise me what's happened there and why has that different?

e.g.
public TestServlet .....{

public void doGet .... {
handleRequest();
}
public void doPost ...{

handleRequest();
}
protected synchronized void handleRequest().....{

}

or protected void handleRequest().....{

}

}
[ October 21, 2008: Message edited by: Bear Bibeault ]
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When multiple clients are hitting the un-synchronized code, a good portion of them will get a speedy reply and your client will do whatever processing it has to with the response. Since you have so many requests your limitation will be the amount of CPU cycles available to process the results - both on the client and the server.

When the clients hit the synchronized code, there will only be one request processed at a time. So the server will have only one request thread processing the requests, with the other server-side request threads waiting for the synchronizing lock. As a result, only 1 client will get a response at a time, so only one client will be able to process the response, while the others have to wait for the servlet to finish up and give it something to do. Your limit is no longer CPU cycles, but the time it takes to get through the synchronized block.

It is usually a bad idea to synchronize a servlet method - there really should be no reason to. Servlets should not contain any state. If your servlet does, then it suggests poor design, you should try to factor the state out of the servlet and into a stateful object (a plain java object or JavaBean) that can either be created per-thread or have sub-sets of methods that are synchronized while control and display remain un-synchronized.
 
Sky Loi
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Steve, thanks for details. My servlet handleRequest method is marked as "synchronized", which was done by previous developer. As there is not any instance or statice variable in my servlet, could I assume it is safe to take the "synchronized" out and still keep thread safe?

By doing this, I encounter the hight CPU usage issue under high volumn concurrency requests. Is that normal?

Thank you in advance.
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65126
92
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, it's safe.

And think about it... if all the threads can execute at once, that would keep the CPU as busy as it's able, no?
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Sky Loi:
Hi, Steve, thanks for details. My servlet handleRequest method is marked as "synchronized", which was done by previous developer. As there is not any instance or statice variable in my servlet, could I assume it is safe to take the "synchronized" out and still keep thread safe?

By doing this, I encounter the hight CPU usage issue under high volumn concurrency requests. Is that normal?

Thank you in advance.


You should look through the code carefully to make sure that there aren't other shared resources. It usually isn't safe to assume that synchronized was put there for no reason - but if you check the code and it looks safe (and your concurrency tests don't show any problems with data sharing) then go ahead and remove it.

It is normal for you to get high load when you have many concurrent requests. That is why we fall back to clustering and load-sharing on systems that expect high-request loads.
 
Sky Loi
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, all, thank you very much. Your advice is indeed helpful.
 
Adam Asham
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
May I ask for guidance related this this topic too?

I have an application in which there's functionality that is to be used by a single user. If the task has been started nobody else is able to start another process until it's completed.

What's the recommended approach for such a scenario? To synchronize the servlet or make a static object representing the task and synchronize the method in the servlet that starts the task?

Adam
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65126
92
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'd rely on explicit queuing rather than implicitly relying upon synchronized to control the execution of the serial process.
[ October 21, 2008: Message edited by: Bear Bibeault ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic