欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[J2EE] Servlet线程不安全的体现以及解决方式 笔记

程序员文章站 2022-05-15 10:58:37
...

        对于实例变量来说,由于servlet在Tomcat中是以单例模式存在的,所有的线程共享实例变量。多个线程对共享资源的访问造成了线程不安全问题。

案例如下:

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @author zWX240091
 *
 */
public class HelloWorldServlet extends HttpServlet
{
    String message;
    /**
     * 
     */
    private static final long serialVersionUID = 787553024399133588L;
    public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
        message =request.getParameter("message");
        PrintWriter pw = response.getWriter();
        try
        {
            Thread.sleep(5000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        pw.write("<div><strong>Hello World</strong>!</div>"+message);
        pw.close();
    }
    
}

在构建好的工程部署到本地Tomcat下,启动Tomcat,打开俩个浏览器

访问1: http://localhost:8080/Servlet03/HelloWorld?message=helloA

访问2: http://localhost:8080/Servlet03/HelloWorld?message=helloB

分别刷新访问,在访问第一个地址的页面打印出了helloB,在访问第二个地址的时候页面有时候会打印出helloA。这个就是高并发下的多线程的安全问题。

 

解决方式:

  1. 添加同步代码锁 synchronized
  2. 将要访问的实例变量改为局部变量多线程下每个线程对局部变量都会有自己的一份copy,这样对局部变量的修改只会影响到自己的copy而不会对别的线程产生影响,线程安全的

 

       扩展笔记:struts1 因为是基于servlet开发的框架,存在安全隐患。所以才催生来后来的struts2(基于filter,摆脱了线程安全问题),但技术上二者并无多少联系,分别属于两个开发团队。

 

资料参考地址:https://www.cnblogs.com/alaskan/p/4178533.html

相关标签: J2EE