Servlet Competition

Original author: Wideskills
  • Transfer
Hello!

We are launching the seventh Java Developer course thread . For more than a year of existence of this course, he was refining, honing, adding a new one, which was published during this time. The same flow differs from the others in that we introduced a new system of steps, breaking the course into three parts and slightly increasing its overall duration. So now it will not be necessary to get out of power for five months in a row to receive a certificate, but calmly choose periods of two months and go through training. But this is the lyrics, let us return to our tradition about the different usefulness of the course that precedes the launch.

Go.

1. Overview


A Java servlet container (or web server) is multi-threaded: multiple requests to a single servlet can be executed at the same time. Therefore, when writing a servlet must take into account the competition.

As we said earlier, one and only one instance of the servlet is created, and for each new request, the Servlet Container creates a new stream to execute the servlet's doGet () or doPost () methods.

By default, servlets are not thread-safe, the programmer himself must take care of this. In this chapter, we discuss servlet contention. This is a very important concept, so focus.

2. Overview of threads




A thread is a lightweight process that has its own call stack and uses access to open data from other threads in the same process (shared heap). Each thread has its own cache.

When we say that a program is multi-threaded, we mean that the same instance of an object spawns several threads and processes a single element of code. This means that several consecutive control flows through the same block of memory. Thus, several threads execute one instance of the program and, therefore, share the instance variables and may attempt to read and write these common variables.

Let's look at a simple Java example.

publicclassCounter{
	int counter=10;
	publicvoiddoSomething(){
	    System.out.println(“Inital Counter = ” + counter);
	    counter ++;
	    System.out.println(“Post Increment Counter = ” + counter);
	}
}
 

Now we create two threads Thread1 and Thread2 for execution doSomething(). As a result, it is possible that:

  1. Thread1 reads a counter value of 10
  2. Displays Inital Counter = 10 and is going to increment
  3. Before Thread1 increments the counter, Thread2 also increments the counter by changing the counter value by 11
  4. As a result, Thread1 has a counter value of 10, which is already out of date.

This script is possible in a multithreaded environment, such as servlets, because instance variables are shared by all threads running in a single instance.

3. We write thread-safe servlets


I hope in this section you will understand the problems that I am trying to highlight. If you have any doubts, read point 2 again.

There are some points that we should consider when writing servlets.

  1. Service(), doGet(), doPost()Or, more generally, the methods doXXX()do not need to update or change the instance variables because instance variables are shared by all threads of the same instance.
  2. If there is a need to modify an instance variable, then do it in a synchronized block.
  3. Both of the above rules apply to static variables also because they are also common.
  4. Local variables are always thread-safe.
  5. The request and response objects are thread-safe to use, because a new instance is created for each request to your servlet and, therefore, for each stream executed in your servlet.

Below are two approaches to ensuring thread safety:

a) Synchronize the block in which you change the instance or static variables (see the code snippet below).

We recommend synchronizing the block in which your code changes the instance variables instead of synchronizing the full method for the sake of improving performance.

Notice that we need to lock the servlet instance, since we have to make a particular instance of the servlet thread safe.

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
publicclassThreadSafeServletextendsHttpServlet{
@overridepublicvoiddoGet(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 — implement the SingleThreadModel interface to make the thread single-threaded, which means that only one thread will execute the service () or doXXX () method at a time. Single-threaded servlet is slower under load, because new requests must wait for a free instance to be processed

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
publicclassThreadSafeServletextendsHttpServletimplementsSingleThreadModel{
int counter;
// no need to synchronize as implemented SingleThreadModel@overridepublicvoiddoGet(HttpServletRequest request, 
	                HttpServletResponse response)throws ServletException, IOException
 { 
  } 

Using SingleThreadModel is deprecated, since it is recommended to use synchronized blocks.

4. Conclusion


We have to be very careful when writing servlets, since “by default, servlets are not thread safe”

  1. If your servlet does not have any static or member variable, you do not need to worry and your servlet is thread-safe.
  2. If your servlet just reads an instance variable, your servlet is thread safe.
  3. If you need to change an instance or static variables, update it in a synchronized block while holding the instance lock.

If you follow the rules above, and the next time someone asks you, “Is the servlet thread safe?” - answer confidently: “By default, they are not, but My Servlets are thread safe.”

THE END

As always, we are waiting for your questions, suggestions, etc. here or you can ask them to Sergei Petrelevich at the Open lesson on the dedicated thread.

Also popular now: