博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java面试题:Servlet是线程安全的吗?
阅读量:6767 次
发布时间:2019-06-26

本文共 1677 字,大约阅读时间需要 5 分钟。

转自: 

 

Servlet不是线程安全的。

要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的。

当Tomcat接收到Client的HTTP请求时,Tomcat从线程池中取出一个线程,之后找到该请求对应的Servlet对象。如果该Servlet还未被请求过,那么将进行Servlet初始化并调用Servlet并调用service()方法。否则,直接调用service()方法。要注意的是每一个Servlet对象再Tomcat容器中只有一个实例对象,即是单例模式。如果多个HTTP请求请求的是同一个Servlet,那么着两个HTTP请求对应的线程将并发调用Servlet的service()方法。

这时候,如果在Servlet中定义了实例变量或静态变量,那么可能会发生线程安全问题(因为所有的线程都可能使用这些变量)。

比如下面的Servlet中的namei变量就会引发线程安全问题。

import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;public class ThreadSafeServlet extends HttpServlet {    public static String name = "Hello";   //静态变量,可能发生线程安全问题    int i;  //实例变量,可能发生线程安全问题    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");    @Override    public void init() throws ServletException {        super.init();        System.out.println("Servlet初始化");    }    @Override    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        System.out.printf("%s:%s[%s]\n", Thread.currentThread().getName(), i, format.format(new Date()));        i++;        try {            Thread.sleep(5000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.printf("%s:%s[%s]\n", Thread.currentThread().getName(), i, format.format(new Date()));        resp.getWriter().println("

" + i + "

"); }}

 

在Tomcat中启动这个Servlet并在浏览器发起多个HTTP访问,最后会发现变量i是多线程共享的。

如果需要更加深入透彻地了解Tomcat接收HTTP的细节,以及与Servlet交互的细节,可以深入看看Tomcat的架构和源码。

参考资料:

1、
2、

转载地址:http://jiseo.baihongyu.com/

你可能感兴趣的文章
软件公司 之 老马与新马
查看>>
怎么提加薪水的办法
查看>>
NTP时间服务器
查看>>
与域控制器失去信任关系问题排查
查看>>
golang 并发二(调度)
查看>>
家里人病了
查看>>
一个老板向员工发的牢骚
查看>>
ESRS 转发Alert
查看>>
中层管理者的难题,“结果”还是“过程”?
查看>>
linux 目录及文件操作
查看>>
QPainter类 详解
查看>>
SpringMVC的工作流程
查看>>
我的友情链接
查看>>
Scala的bounds
查看>>
Project Euler 8 Largest product in a series
查看>>
TinyXml 使用注意事项
查看>>
virtualbox-网络地址转换()NAT)模式下搭建个人局域网
查看>>
如何使用multipart/form-data格式上传文件
查看>>
django路由和模板
查看>>
nginx socket支持php
查看>>