12 - Concurrency in Servlets

12.1 Overview

A Java servlet container or web server is multithreaded and multiple requests to the same servlet may be executed at the same time. Therefore, we need to take concurrency into consideration while writing servlet.

As we discussed earlier that one and only one instance of Servlet gets created and for every new request , Servlet Container spawn a new thread to execute doGet() or doPost() methof of a servlet.

By default servlets are not thread safe and it is a responsibility of  a servlet developer to take care of it.

In this chapter we will discuss about concurrency in servlets and this is very important concept so your attention is required.

12.2 Threads Overview   

A thread is a lightweight process which has its own call stack and accesses shared data of other threads in the same process (shares heap memory). Every thread has its own memory cache.

When we say that a program is multithreaded, we mean that same instance of an object  spawns multiple threads and process this single instance of code. This means that more than one sequential flow of control runs through the same memory block. So multiple threads execute a single instance of a program and therefore shares instance variables  and  could possibly be attempting to read and write those shared variable.

Lets take a simple java example

public class Counter
{
    int counter=10;
    public void doSomething()
    {
        System.out.println(“Inital Counter = ” + counter);
        counter ++;
        System.out.println(“Post Increment Counter = ” + counter);
    }
}

Now we execute two threads Thread1 and Thread2 to execute doSomething() method. So it is possible that

  1. Thread1 reads the value of counter which is 10
  2. Displays the Inital Counter =10 and increment
  3. Before actually Thread1 increments the counter another Thread1 increments the counter  which changed the value of counter to 11
  4. Now Thread1 has value of counter as 10 which is stale now

This scenario is possible in multithreaded environment like servlets and it is because instance variables are shared by all threads running in same instance.

Same can be the issue with the Servlets also.

12.3 Write Thread Safe Servlets

I hope by this section you understand the concerns I am trying to highlight. If you have even a small doubt , read Section 12.2 one more time.

There are certain points which we should consider while writing servlets.

  1. Service() , doGet(), doPost() or to be more generic doXXX()  methods should not update or modify instance variables as instance variables are shared by all threads of same instance.
  1. If you have a requirement which requires modification of instance variable then do it in a synchronized block.
  1. Above two rules are applicable for static variables also because they are also shared.
  1. Local variables are always thread safe.
  1. The request and response objects are thread safe to use because new instance of these are created for every request into your servlet, and thus for every thread executing in your servlet.

Below are the two approaches to make the thread safe

  1. Synchronized the block where you are modifying instance or static variables.(refer below code snipped).

We recommend to synchronize the block where your code modifies the instance variables instead of synchronizing complete method for the sake of performance.

Note that we need to take a lock on servlet instance as we need to make the particular servlet instance as tread safe.

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ThreadSafeServlet extends HttpServlet {
@override   
public void doGet (HttpServletRequest request, 
                    HttpServletResponse response)
   throws ServletException, IOException
    int counter;
     { 
             synchronized (this) {
             //code in this block is thread-safe so update the instance variable
              }
      //other processing;
  } 

 b) Single Thread Model –Implements  SingleThreadModel interface to make our thread single threaded which means only one thread will execute service() or doXXX() method at a time. A single-threaded servlet is slower under load because new requests must wait for a free instance in order to proceed

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ThreadSafeServlet extends HttpServlet implements SingleThreadModel {
int counter;
// no need to synchronize as implemented SingleThreadModel
@override   
public void doGet (HttpServletRequest request, 
                    HttpServletResponse response)
   throws ServletException, IOException
 { 
  } 

Use of SingleThreadModel is deprecated as advisable to use synchronized block

12.4 Conclusion

We need to be very careful while writing servlets as “by default servlets are not thread safe”.

  • If your servlet does not have any static or member variable then no need to worry and your servlet is thread safe
  • If your servlet just reads the instance variable then your servlet is thread safe.
  • If you need to modify the instance or static variables , update it in a synchronized block while holding a lock on Servlet instance

 If you follow above rules and next time if someone asks you “Are servlet thread safe? “ then answer confidently  “ By default they are not but My Servlets are thread safe”  .

Like us on Facebook