I am working on a JSP MVC web application. I am confused about Thread-Safe Servlet concept. Following is my code, please tell me is it thread safe or not. Also, tell me the reason that why it is thread-safe or not thread-safe.
JSP Code;
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Personal Profile</title>
</head>
<body>
<form id="PersonalData" method="post" action="PersonalDataServlet">
First Name:<input type="input" name="FirstNameField"><br>
Last Name:<input type="input" name="LastNameField"><br>
Email:<input type="input" name="EmailField">Without @ part<br>
<input type="Submit" value="Submit Data">
</form>
<br>
<br>
<br>
<%
out.print(request.getAttribute("FullName") + "\n");
out.print(request.getAttribute("EmailAddress"));
%>
</body>
</html>
Servlet Code;
package Servlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import Model.WelcomeName;
@WebServlet("/PersonalDataServlet")
public class PersonalDataServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String FirstNameServlet;
String LastNameServlet;
String EmailServlet;
FirstNameServlet = request.getParameter("FirstNameField");
LastNameServlet = request.getParameter("LastNameField");
EmailServlet = request.getParameter("EmailField");
System.out.println(FirstNameServlet + "\n" + LastNameServlet + "\n" + EmailServlet);
WelcomeName WelcomeNameObject = new WelcomeName();
WelcomeNameObject.Fullname(FirstNameServlet, LastNameServlet, EmailServlet);
request.setAttribute("FullName", WelcomeNameObject.FullName);
request.setAttribute("EmailAddress", WelcomeNameObject.EmailAddress);
request.getRequestDispatcher("Profile.jsp").forward(request, response);
}
}
Other Class Which is used to the actual calculation or Business Logic
package Model;
public class WelcomeName {
public String FullName;
public String EmailAddress;
public void Fullname(String FirstName, String LastName, String Email) {
FullName = (FirstName + " " + LastName);
EmailAddress = (Email + "@gmail.com");
}
}
2 Answers 2
Yes, this is completely thread-safe. When arguing whether a class or a method is thread-safe or not, you should look at some state that is shared between multiple threads. If no state is shared between threads then the class is thread-safe. (This is the principle behind immutable classes, and it is what makes them thread-safe as well).
In your case, the class PersonalDataServlet
is a web servlet, so the instance is shared among all requests. This means that the potential shared state would be state of the instance itself. But your instance does not store or update any instance variables: all the processing is done with local variables inside the doPost
method. This ensures thread-safety.
To give you an example, you currently have
@WebServlet("/PersonalDataServlet")
public class PersonalDataServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String FirstNameServlet;
FirstNameServlet = request.getParameter("FirstNameField");
// ...
}
Since FirstNameServlet
is a local variable, everything is fine. Now, if you had written:
@WebServlet("/PersonalDataServlet")
public class PersonalDataServlet extends HttpServlet {
private String FirstNameServlet;
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
FirstNameServlet = request.getParameter("FirstNameField");
// ...
}
Then you would have lost thread-safety: this is because this code mutates an instance variable of the class and, so, this variable will be shared among all requests. If another request is made concurrently, it could update the value of the instance variable while the first request is still processing and mess up its results.
I will continue with general comments of your code:
- Respect Java naming conventions:
FirstNameServlet
(and the others) should be namedfirstNameServlet
with a lowercase letter at the start. Note that you could rename it simplyfirstName
, which is shorter and still conveys the meaning of the variable. You can declare and initialize your variable at the same time. Instead of
String FirstNameServlet; String LastNameServlet; String EmailServlet; FirstNameServlet = request.getParameter("FirstNameField"); LastNameServlet = request.getParameter("LastNameField"); EmailServlet = request.getParameter("EmailField");
consider writing
String firstName = request.getParameter("FirstNameField"); String lastName = request.getParameter("LastNameField"); String email = request.getParameter("EmailField");
which is a lot shorter and still easy to read.
Make use of the constructors. You are currently initializing your
WelcomeName
class withWelcomeName WelcomeNameObject = new WelcomeName(); WelcomeNameObject.Fullname(FirstNameServlet, LastNameServlet, EmailServlet);
This is awkward since you have two steps to construct your object: a default constructor for an empty non-initialized-yet object and a method for finishing it. Consider creating a proper constructor taking all the parameters. In fact, you don't need that class at all: you could simplify this by removing it completely.
- Don't use scriptlets inside your JSP pages. This is a bad habit and you should drop it.
It is thread safe. It's because your Servlet class doesn't declare anything outside the scope of the doPost
method.
You don't control how many Servlets you have or when they are created/destroyed, your Servlet container does, but, as long as you keep the class with no members it'll be thread safe. You might find this article useful.
Let's check out an example of a non thread safe servlet:
@WebServlet("/PersonalDataServlet")
public class PersonalDataServlet extends HttpServlet {
boolean locked;
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (!locked){
locked = true;
// Process
locked = false
}
}
}
The code above wouldn't work in multi-threaded environments, because different threads could execute doPost
at different times, so you couldn't trust in the lock
field.
Explore related questions
See similar questions with these tags.