Servlet不是线程安全的。

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

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

上图中的Thread1和Thread2调用了同一个Servlet1,所以此时如果Servlet1中定义了实例变量或静态变量,那么可能会发生线程安全问题(因为所有的线程都可能使用这些变量)。

比如下面的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("<html><body><h1>" + i + "</h1></body></html>");
}
}

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

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

参考资料

1、http://www.ibm.com/developerworks/cn/java/j-lo-tomcat1/

2、http://blog.csdn.net/cutesource/article/details/5040417

3、Tomcat的线程模型

Java面试题:Servlet是线程安全的吗?的更多相关文章

  1. Java面试题-线程安全

    1. 什么叫线程安全?servlet是线程安全吗?       答:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他 ...

  2. Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)

    一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会 ...

  3. Java 面试题 三 <JavaWeb应用调优线程池 JVM原理及调优>

    1.Java Web应用调优线程池 不论你是否关注,Java Web应用都或多或少的使用了线程池来处理请求.线程池的实现细节可能会被忽视,但是有关于线程池的使用和调优迟早是需要了解的.本文由浅入深,介 ...

  4. 一道非常棘手的 Java 面试题:i++ 是线程安全的吗

    转载自  一道非常棘手的 Java 面试题:i++ 是线程安全的吗 i++ 是线程安全的吗? 相信很多中高级的 Java 面试者都遇到过这个问题,很多对这个不是很清楚的肯定是一脸蒙逼.内心肯定还在质疑 ...

  5. Java面试题总结系列 Servlet

    Servlet技术主要是为了使用Web上的HTTP协议而设计的.servlet是在WEB服务器上运行的程序.Java Servlet可以用于处理客户请求或生成动态Web网页.先一个实例.然后解释. 先 ...

  6. [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html   谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...

  7. java面试题及答案(转载)

    JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时 ...

  8. 115个Java面试题和答案——终极列表(下)

    第一篇讨论了面向对象编程和它的特点,关于Java和它的功能的常见问题,Java的集合类,垃圾收集器,本章主要讨论异常处理,Java小应用程序,Swing,JDBC,远程方法调用(RMI),Servle ...

  9. Java面试题(全)

    JAVA部分 什么是反射机制?反射机制应用(Struts中反射机制的应用) 答:运行状态中,对于任意一个类,都可以知道它的所有属性和方法,对于任意一个对象都可以调用它的任意一个方法,这种动态获取信息以 ...

  10. java 考试试题

    Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io 的语法,虚拟机方面的语法,其他.有些题来自网上搜集整理,有些题来自学员 ...

随机推荐

  1. A manager is becoming more and more popular in China

    A manager is becoming more and more popular in China; many people want to possess a position like th ...

  2. 业务逻辑 : 未完 : easybook.com

    Content>social media facebook, twitter, google+, instagram, pinterest (Question : How to update n ...

  3. 每天一个Linux命令(17)--whereis命令

    whereis 命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s).如果省略参数,则返所有信息. 和find相比,whereis查找的速度非 ...

  4. JavaScript定义函数的三种方式

    直接定义函数 function f1(x,y){ return x+y; } 使用Function构造函数 var f2=new Function("x","y" ...

  5. 2017 3-4/5 两天的学习的REVIEW

    明天就要去面试啦,去感受一下,估计又是一顿虐,蓝瘦-- 3月4日:计算机安全基础技术与原理方面的学习 密码体制(密码)由五个部分组成: 消息空间(m),密文空间(c),密钥空间(k),加密算法(E), ...

  6. for循环的表达规则,for循环的嵌套,跳转语句;穷举;迭代;异常处理

    for循环的基本格式 for(表达式1:表达式2:表达式3) { 循环体: } for循环的四要素 表达式1就是变量初始化:表达式2就是循环条件:表达式3是状态改变 static void Main( ...

  7. Archlinux 升级 pacman 时遇到的问题及其解决

    这是 Archlinux 升级时经常碰到的老问题.提示如下 问题来了 # yaourt -Syua ==> 警告:使用 root 用户构建软件包存在风险. 请使用非特权用户运行 yaourt . ...

  8. Android -- 仿小红书欢迎界面

    1,觉得小红书的欢迎界面感觉很漂亮,就像来学习学习一下来实现类似于这种效果  原效果图如下: 2,根据效果我们来一点点分析 第一步:首先看一下我们的主界面布局文件视图效果如下: main_activi ...

  9. TIME_WAIT问题总结

         最近用http_load做压测,跑出来一大串"Cannot assign requested address "的错误,查了一下,是TIME_WAIT过多导致的.因为短时 ...

  10. Webdriver初探

    1.启动Firefox浏览器失败 package org.coder.demo; import org.openqa.selenium.*; import org.openqa.selenium.We ...