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.
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 create two threads Thread1 and Thread2 for doing
doSomething()
. As a result, it is possible that:
- Thread1 reads a counter value of 10
- Displays Inital Counter = 10 and is going to increment
- Before Thread1 increments the counter, Thread2 also increments the counter by changing the counter value by 11
- 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.
Service()
, doGet()
, doPost()
or, more generally, doXXX()
methods should not update or modify instance variables, since instance variables are shared by all threads of the same instance.- If there is a need to modify an instance variable, then do it in a synchronized block.
- Both of the above rules apply to static variables also because they are also common.
- Local variables are always thread-safe.
- 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 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.*; public class ThreadSafeServlet extends HttpServlet { @override public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException int counter; { synchronized (this) {
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.*; public class ThreadSafeServlet extends HttpServlet implements SingleThreadModel { int counter;
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”
- If your servlet does not have any static or member variable, you do not need to worry and your servlet is thread-safe.
- If your servlet just reads an instance variable, your servlet is thread safe.
- 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.