Servlet是线程安全的吗?
Servlet不是线程安全的。
要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的。
当Tomcat接收到Client的HTTP请求时,Tomcat从线程池中取出一个线程,之后找到该请求对应的Servlet对象并进行初始化,之后调用service()方法。要注意的是每一个Servlet对象再Tomcat容器中只有一个实例对象,即是单例模式。如果多个HTTP请求请求的是同一个Servlet,那么着两个HTTP请求对应的线程将并发调用Servlet的service()方法。
上图中的Thread1和Thread2调用了同一个Servlet1,所以此时如果Servlet1中定义了实例变量或静态变量,那么可能会发生线程安全问题(因为所有的线程都可能使用这些变量)。
比如下面的Servlet中的 name
和 i
变量就会引发线程安全问题。
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("<html><body><h1>" + i + "</h1></body></html>");
}
}
在Tomcat中启动这个Servlet并在浏览器发起多个HTTP访问,最后会发现变量 i
是多线程共享的。
如果需要更加深入透彻地了解Tomcat接收HTTP的细节,以及与Servlet交互的细节,可以深入看看Tomcat的架构和源码。
Servlet是线程安全的吗?的更多相关文章
- Servlet 是否线程安全 看完便知
Servlet 是否线程安全 看完便知 转自:http://blog.sina.com.cn/s/blog_6448959f0100kct7.html 摘 要:介绍了Servlet多线程机制, ...
- 玩转Web之servlet(五)---- 怎样解决servlet的线程安全问题
servlet默认是存在线程安全问题的,但是说白了,servlet的线程安全问题实际上就是多线程的线程安全问题,因为servlet恰巧是一个多线程才会出现安全性问题. 浏览器每次通过http协议去提交 ...
- Servlet的线程安全
Servlet的线程安全 一.什么是Servlet的线程安全 1.在Servlet的整个生命周期中,构造方法只被执行一次.也就是说,在Servlet的整个生命周期中,只存在一个Servlet实例对象. ...
- servlet是线程安全的么
servlet生命周期 三个重要方法 1 init() 进行资源的加载 2 service() 处理请求,根据请求方式,调用doGet或者doPost 3 destroy() 进行资源的释放 ser ...
- 漫画 | Servlet属于线程安全的吗?
Servlet属于线程安全的吗? Servlet不是线程安全的 在JSP中,只有一行代码:<%=A+B %>,运行结果如何? jsp和servlet有什么关系? jsp一般被用在view层 ...
- servlet开发(二)之servlet的线程安全问题
之所以考虑线程安全问题,是因为引入了多线程.多线程指的是这个程序(一个进程)运行时产生了不止一个线程.如果不考虑多线程的话,程序执行只有一条路径,就像人在敲代码的时候只能敲代码,不能戴上耳机听歌.引入 ...
- servlet与线程与jdbc connection的关系
servlet与线程与jdbc connection的关系 都是一一绑定的关系, servlet接受那么多此请求. 一个请求,对应一个线程,对应一个DB POOL的connection. 因为conn ...
- Java面试题:Servlet是线程安全的吗?
Servlet不是线程安全的. 要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP请求时 ...
- servlet 最大线程数探索笔记
servlet默认是单例模式的,所以是单例多线程的.如果实现了singleservlet是可以多个servlet实例,下面是一个servlet的请求生命周期 1 客户端请求该 Servlet:加载 S ...
- Servlet的线程是不是共享同一个requset对象及servlet多线程
servlet多线程 一,servlet容器如何同时处理多个请求. Servlet采用多线程来处理多个请求同时访问,Servelet容器维护了一个线程池来服务请求.线程池实际上是等待执行代码的一组 ...
随机推荐
- git ssh密钥的使用
//配置邮箱,用户名, git config --global user.name git config --global user.email git config --global --list ...
- excel测试数据导入
需求背景:测试数据的导入一般在dataprovider中写入对应的测试数据,当参数较多,组合测试或者接口参数测试的测试数据都需要逐一写数据驱动类,数据准备消耗了大量时间.前一篇博客中介绍了对偶测试的小 ...
- 异步解决方案(三)Promise
首先建议大家先看看这篇博文,这是我看过的最清晰给力的博文了: https://www.cnblogs.com/lvdabao/p/es6-promise-1.html 附赠一篇笑死我了的博客,加入有一 ...
- [PowerShell] check PowerShell Version
如果你已经开始在日常的工作中大量使用PowerShell自动化重复工作.建议你使用3.0以上的版本. 可以使用如下命令检测你的PS版本 如需要安装PowerShell,可以参看https://tech ...
- 解决:安装Jenkins时web界面出现该jenkins实例似乎已离线
很久没有安装jenkins了,因为之前用的的服务器一直正常使用,令人郁闷的是,之前用jenkins一直没出过这个问题. 令人更郁闷的是,我尝试了好多个历史版本和最新版本,甚至从之前的服务器把jenki ...
- 多数据源 + Configuration中bean依赖注入顺序问题
为什么要调用方法,而不是直接autowire? 官方文档 https://docs.spring.io/spring-boot/docs/current/reference/html/howto-da ...
- Python入妖4-----Request库的基本使用
什么是Requests Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库如果你看过上篇文章关于urllib库的使用,你会发现,其 ...
- ubuntu ifconfig 不显示IP地址
本文转载:https://blog.csdn.net/cmh477660693/article/details/52760236 ubuntu终端下命令ifconfig的问题解决 问题一. ifcon ...
- Hadoop 2.0 安装配置
1. install jdk 2. install hadoop. 安装包hadoop-2.2.0.tar.gz存放在一个目录.并解压. 3. 修改配置文件,一般配置文件在/etc/hadoop下面. ...
- python3 importlib模块简单利用
importlib作用:根据字符串形式导入模块,并且找到其中的类并执行 import importlib # m = importlib.import_module("src.plugins ...