关闭

【java学习准备2】servlet是线程安全的吗?

标签: servletjava线程安全
47人阅读 评论(1) 收藏 举报
分类:

原文地址:https://www.cnblogs.com/itTeacher/archive/2012/11/14/2769822.html

前两天,有个人问我“servlet是线程安全的吗?“,我却很难给出一个很具体清晰的回答,今天重新整理一下思路,也复习一下那些被扔回给老师的理论。

servlet是线程安全的吗?

这个问题,在网上没有看到一个确切的答案,所以我们来分析一下:
首先什么是线程安全?
引用概念:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

那么我们都知道servlet是多线程的,同时一个servlet实现类只会有一个实例对象,也就是它是Singleton的,所以多个线程是可能会访问同一个servlet实例对象的。

每个线程都会为数据实例对象开辟单独的引用,那么servlet会是线程安全的吗?

要判断是否是线程安全,我们需要知道线程安全问题是由什么引起的。
搜索得到答案:线程安全问题都是由全局变量及静态变量引起的。
看到这个答案,突然想起很多年前调查过的一个bug, 那时我们系统中遗留的代码中写了很多全局变量,有一次发布后,客户反馈,当有多人同时进行某个操作时,我们的数据出了问题,那时我们调查后的结果就是:多人同步操作时,有些全局变量的值不对了,之后我们专门设一个人花了很多工夫来将所有全局变量都改成了局部变量了,并且项目要求以后不允许用全局变量。原来那时侯我就已经碰到过线程不安全的情况了啊,不过处理方式或者不用全局,或者加入同步,若加入同步同时也要考虑一下对程序效率会不会产生影响。

由此可知,servlet是否线程安全是由它的实现来决定的,如果它内部的属性或方法会被多个线程改变,它就是线程不安全的,反之,就是线程安全的。

在网上找到一个例子,如下:

public class TestServlet extends HttpServlet {
     private int count = 0;  

     @Override
     protected void service(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         response.getWriter().println("<HTML><BODY>");
         response.getWriter().println(this + " ==> ");
         response.getWriter().println(Thread.currentThread() + ": <br>"); 
         for(int i=0;i<5;i++){
             response.getWriter().println("count = " + count + "<BR>");
             try {
                 Thread.sleep(1000);  
                 count++;  
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
         response.getWriter().println("</BODY></HTML>");
     }
 }

当同时打开多个浏览器,输入http://localhost:8080/ServletTest/TestServlet时,他们显示的结果不同,这就说明了对于属性count来说,它是线程不安全的,
为了解决这个问题,将代码重构,如下:

public class TestServlet extends HttpServlet {
      private int count = 0;  
      private String synchronizeStr = ""; 
      @Override
     protected void service(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         response.getWriter().println("<HTML><BODY>");
         response.getWriter().println(this + " ==> ");
         response.getWriter().println(Thread.currentThread() + ": <br>"); 
         synchronized (synchronizeStr){
             for(int i=0;i<5;i++){
                 response.getWriter().println("count = " + count + "<BR>");
                 try {
                     Thread.sleep(1000);  
                     count++;  
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
         }
         response.getWriter().println("</BODY></HTML>");
     }
 }
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

【Java之Servlet(二)】servlet是单例多线程,以及多线程下如何保证线程安全

Servlet 单例多线程 1、Servlet如何处理多个请求访问? 答:Servlet容器默认是采用单实例多线程的方式处理多个请求的: 1.当web服务器启动的时候(或客户端发送请求到服务器时)...
  • cangchen
  • cangchen
  • 2015-04-22 16:45
  • 2378

java-web之servlet中的线程安全问题

一,servlet容器如何同时处理多个请求。 Servlet采用多线程来处理多个请求同时访问,Servelet容器维护了一个线程池来服务请求。 线程池实际上是等待执行代码的一组线程叫做工作者线...
  • A1023824314
  • A1023824314
  • 2016-07-25 00:01
  • 2797

servlet默认是线程安全的吗

Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。 当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Serv...
  • bruce_6
  • bruce_6
  • 2014-09-09 16:33
  • 2636

java安全学习准备知识(一)

安全的基础知识     在高度保证企业应用程序安全的过程中我们不免会考虑到如下的安全需求,然后我们针对这些安全需求提出各种安全技术:    1、 完整性验证(Integrity Verificati...
  • zzq19860626
  • zzq19860626
  • 2013-08-23 13:54
  • 339

2.Servlet线程安全和ServletConfig以及其它用法

Servlet线程安全和ServletConfig以及其它用法
  • piyingcheng
  • piyingcheng
  • 2016-03-27 22:12
  • 92

Java面试题:Servlet是线程安全的吗?

Servlet不是线程安全的。 要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的。 当Tomcat接收到Client的HTTP请...
  • H12KJGJ
  • H12KJGJ
  • 2017-05-25 17:09
  • 304

Java面试题:Servlet是线程安全的吗?

Servlet**不是线程安全**的。  要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的。  当Tomcat接收到Client的H...
  • qq_36295256
  • qq_36295256
  • 2017-07-26 20:06
  • 226

java的内存机制以及servlet中的线程安全问题简单理解

Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存...
  • Poison__biting
  • Poison__biting
  • 2017-05-09 20:17
  • 159

Servlet 2 (线程安全,配置对象ServletConfig)

五、Servlet的线程安全 单实例:每次访问多线程 解决并发出现的问题,可以采用以下方式: 1  使用Java同步机制对多线程同步:运行效率低 2  使用SingleThreadModel接口(...
  • duoduo18up
  • duoduo18up
  • 2018-01-06 19:43
  • 20

Struts1,2,Servlet,Spring MVC单例多例 线程安全问题

本文章转载于:http://blog.csdn.net/zly9923218/article/details/51125881 Struts 1单例,线程不安全,在请求的时候被第一次初...
  • u012204058
  • u012204058
  • 2016-11-07 14:20
  • 280
    个人资料
    • 访问:196368次
    • 积分:2033
    • 等级:
    • 排名:千里之外
    • 原创:65篇
    • 转载:23篇
    • 译文:1篇
    • 评论:122条
    文章分类
    最新评论