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

标签: servlet java 线程安全
111人阅读 评论(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>");
     }
 }
查看评论

Servlet的多线程和线程安全

原文地址:纸上得来终觉浅 Servlet的多线程和线程安全线程安全 首先说明一下对线程安全的讨论,哪种情况我们可以称作线程安全? 网上对线程安全有很多描述,我比较喜欢《Java并发编程实战》给出的定...
  • qq_24145735
  • qq_24145735
  • 2016-09-04 17:41:41
  • 2513

servlet是线程安全的吗?

前两天,有个人问我“servlet是线程安全的吗?“,我却很难给出一个很具体清晰的回答,今天重新整理一下思路,也复习一下那些被扔回给老师的理论。 servlet是线程安全的吗? 这个问题,...
  • kingmax54212008
  • kingmax54212008
  • 2015-11-10 22:17:05
  • 950

Servlet 是线程安全的吗?

概要Servlet 默认是单例模式,在web 容器中只创建一个实例,所以多个线程同时访问servlet的时候,Servlet是线程不安全的。 那么 web 容器能为每个请求创建一个Servlet的实...
  • jijianshuai
  • jijianshuai
  • 2017-09-07 11:00:14
  • 614

servlet默认是线程安全的吗

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

Servlet—HttpServlet、Servlet线程安全

1. HttpServlet Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。HttpServlet指能够处理HTTP请求的servle...
  • Xw_Classmate
  • Xw_Classmate
  • 2016-02-21 17:36:19
  • 718

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

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

servlet线程安全问题的详解

摘 要:介绍了Servlet多线程机制,通过一个实例并结合Java 的内存模型说明引起Servlet线程不安全的原因,给出了保证Servlet线程安全的三种解决方案,并说明三种方案在实际开发中的取舍。...
  • after_you
  • after_you
  • 2017-01-07 13:28:11
  • 1075

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

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

过滤器、监听器、上下文、servlet线程安全问题

就像名字写那样,过滤器可以过滤请求,比如对一些评论进行过滤。又不改原有代码的基础上可以加上一个过滤器,或者是登陆验证。集中在一个过滤器中处理。写一个类实现接口 Filter 之后一定要在配置文件中配置...
  • qq_28295425
  • qq_28295425
  • 2016-12-12 09:38:55
  • 3128

JSP/Servlet线程安全

在进行servlet开发时,线程安全是很重要的,否则会导致一些意想不到的结果。 Servlet的生命周期是由Web容器负责的,当客户端第一次请求Servlet时,容器负责初始化Servlet,也就是...
  • itcolossus
  • itcolossus
  • 2014-10-27 22:34:39
  • 1212
    个人资料
    持之以恒
    等级:
    访问量: 21万+
    积分: 2192
    排名: 2万+
    最新评论