线程安全Servlet

时间:2016-04-29 16:59:39

标签: java multithreading jsp servlets thread-safety

我正在研究JSP MVC Web应用程序。我对Thread-Safe Servlet概念感到困惑。以下是我的代码,请告诉我线程安全与否。另外,请告诉我它为什么是线程安全的或不是线程安全的原因。

JSP代码;

 <%@ 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代码;

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

    }

}

其他类用于实际计算或业务逻辑

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

}

3 个答案:

答案 0 :(得分:0)

我看到您提供的代码中没有线程安全问题。线程安全主要取决于代码如何使用共享数据,因此我寻找

  • servlet类的实例变量,如果servlet容器使用相同的servlet实例为多个线程中的请求提供服务,则在线程之间共享;

  • 通过servlet上下文或会话对象共享的对象;以及

  • servlet或JSP访问的任何类的静态变量。

这些不是共享数据可以采用的唯一形式,但它们可能适用于您的Web应用程序,就像您提供的那样。您没有通过任何这些机制共享任何数据,因此您提供的servlet和JSP是线程安全的。

如果您 访问共享对象,那么这不会自动使您的代码非线程安全,但您需要通过适当的同步来保护您的访问,以确保其线程安全。作为一个功能问题,您还需要注意同步,以避免在任何相当长的时间内阻塞线程。

答案 1 :(得分:0)

每个方法调用都有自己的堆栈帧,没有其他线程访问它。所有局部变量都在此堆栈帧上分配。对于WelcomeNameObject,它是在堆上创建的,但是对它的唯一引用是在创建它的方法调用的堆栈框架上,以及在请求对象上(即使请求对象在welcomeNameObject上发生了某些变化,那么方法调用就完成了,所以没有冲突)。其他线程没有机会获得对它的引用并进行更改,因此它是线程安全的。

如果移动welcomeName变量的声明,使其成为servlet中的实例变量:

@WebServlet("/PersonalDataServlet")
public class PersonalDataServlet extends HttpServlet {

    private WelcomeName WelcomeNameObject;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

然后结果将是不安全的。 servlet容器保留一个线程池来执行请求,它将这些请求发送到servlet的同一个实例,因此并发请求可以修改servlet的实例变量的内容。例如,一个线程可能进入方法,创建对象的新实例并将其分配给实例变量,然后填充它,然后另一个线程可以调用该方法并创建该对象的新实例并指定 < / em>到同一个实例变量,这样第一次调用就会返回一个与刚刚创建的对象完全不同的对象。

答案 2 :(得分:-1)

您可以使用SingleThreadModel。你的servlet类实现了这个接口,之后你的servlet是线程安全的。