博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
servlet是线程安全的吗?
阅读量:6058 次
发布时间:2019-06-20

本文共 2049 字,大约阅读时间需要 6 分钟。

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>");
     }
 }

转载于:https://www.cnblogs.com/zht214/p/8299434.html

你可能感兴趣的文章
提高网站速度的实践
查看>>
统一项目管理平台(UMPlatForm.NET) 4.11 角色权限管理
查看>>
bzoj 2186: [Sdoi2008]沙拉公主的困惑
查看>>
Cisco Nexus 7000 configuration 基本配置
查看>>
SpringBoot Mybatis双数据源的配置
查看>>
WPF GridView中的CellTemplate失效的原因
查看>>
获得手机屏幕相关参数
查看>>
网站内容禁止复制解决办法
查看>>
我的友情链接
查看>>
使用yum安装软件出现“The requested URL returned error: 404”解决方法
查看>>
负载均衡:四层,七层模型详解
查看>>
Qt多线程
查看>>
学习linux决心书
查看>>
html5+Storage使用
查看>>
Java String
查看>>
统计vs机器学习,数据领域的“少林和武当”
查看>>
我的友情链接
查看>>
大数据如何改变安全视角
查看>>
FastDFS安装配置过程
查看>>
程序包管理:RPM YUM的总结
查看>>