5
\$\begingroup\$

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");
    }

}
\$\endgroup\$
2
\$\begingroup\$

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 named firstNameServlet with a lowercase letter at the start. Note that you could rename it simply firstName, 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 with

    WelcomeName 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.
\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.