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不是线程安全的。的更多相关文章
- javaweb学习总结二十三(servlet开发之线程安全问题)
一:servlet线程安全问题发生的条件 如果多个客户端访问同一个servlet时,发生线程安全问题,那么它们访问的是相同的资源.如果访问 的不是相同资源,则不存在线程安全问题. 实例1:不会产生线程 ...
- servlet 默认是线程安全的吗?
由于Servlet默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的安全问题.然而,很多人编写Servlet程序时并没 有注意到多线程安全的问题,这往往造成编写的程序在少量用户访问 ...
- Java Web学习笔记-Servlet不是线程安全的
由于Servlet只会有一个实例,多个用户同时请求同一个Servlet时,Tomcat会派生出多条线程执行Servlet的代码,因此Servlet有线程不安全的隐患.如果设计不当,系统就会出现问题. ...
- JavaWeb——Servlet如何调用线程池中的线程?
tomcat线程池与servlet https://blog.csdn.net/qq_27817797/article/details/54025173 https://blog.csdn.net/l ...
- servlet的生命周期与运行时的线程模型
第 14 章 生命周期 注意 讲一下servlet的生命周期与运行时的线程模型,对了解servlet的运行原理有所帮助,这样才能避免一些有冲突的设计. 如果你不满足以下任一条件,请继续阅读,否则请跳过 ...
- javaweb回顾第六篇谈一谈Servlet线程安全问题
前言:前面说了很多关于Servlet的一些基础知识,这一篇主要说一下关于Servlet的线程安全问题. 1:多线程的Servlet模型 要想弄清Servlet线程安全我们必须先要明白Servlet实例 ...
- JavaWeb学习之Servlet(三)----Servlet的映射匹配问题、线程安全问题
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140529.html 一.Servlet映射匹配问题: 在第一篇文章中的 ...
- Java面试题:Servlet是线程安全的吗?
Servlet不是线程安全的. 要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP请求时 ...
- Servlet, Struts2和SpringMVC 并发访问线程安全问题
第一部分: Servlet不是线程安全的. 要解释Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP ...
随机推荐
- Deep Learning(4)
四.拓展学习推荐 Deep Learning 经典阅读材料: The monograph or review paper Learning Deep Architectures for AI (Fou ...
- java多线程(六)
使用Runnable接口创建线程 Runnable接口 只有一个run()方法 Thread类实现了Runable接口 便于多个线程共享资源 Java不支持多继承,如果已经继承了某个基类,便要实现Ru ...
- 自定义 Repository 方法
为某一个 Repository 上添加自定义方法 步骤: 定义一个接口: 声明要添加的, 并自实现的方法 提供该接口的实现类: 类名需在要声明的 Repository 后添加 Impl, 并实现方法 ...
- sudo pm2 提示 找不到命令
一共有 3 台 staging 环境服务器,5 台生产环境服务器,centos7系统.前阵子刚给所有研发配置了自己的账号,今天有小伙伴说,在其中两台服务器上 sudo pm2 list 提示: sud ...
- nvm命令行操作命令
1,nvm nvm list 是查找本电脑上所有的node版本 - nvm list 查看已经安装的版本 - nvm list installed 查看已经安装的版本 - nvm list avail ...
- 使用Git【转】
本文转载自:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 我们一直用GitHub ...
- Knockout 监控数组对象属性
代码: function Product(ProductID,ProductName,ProductNum,Result,Price) { this.ProductID = ko.observable ...
- G_M_C_美食节
美食节 题解:学习了动态加边,可以说是进一步理解了网络流.具体思路就是考虑每一道菜,如果这是该位厨师最后一次做,那么等待时间就是做这道菜的时间,如果是倒数第二次做,就要两倍时间(目前做了一次,后面还有 ...
- Codeforces Round #278 (Div. 2) D. Strip 线段树优化dp
D. Strip time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...
- 51nod 1225 余数的和 数学
1225 余数之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 F(n) = (n % 1) + (n % 2) + (n % 3) + ... ...