知识大全 深入研究Servlet线程安全性问题

Posted

篇首语:农村四月闲人少,勤学苦攻把名扬。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 深入研究Servlet线程安全性问题相关的知识,希望对你有一定的参考价值。

深入研究Servlet线程安全性问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  Servlet/JSP技术和ASP PHP等相比 由于其多线程运行而具有很高的执行效率 由于Servlet/JSP默认是以多线程模式执行的 所以 在编写代码时需要非常细致地考虑多线程的安全性问题 然而 很多人编写Servlet/JSP程序时并没有注意到多线程安全性的问题 这往往造成编写的程序在少量用户访问时没有任何问题 而在并发用户上升到一定值时 就会经常出现一些莫明其妙的问题      Servlet的多线程机制    Servlet体系结构是建立在Java多线程机制之上的 它的生命周期是由Web容器负责的 当客户端第一次请求某个Servlet时 Servlet容器将会根据web xml配置文件实例化这个Servlet类 当有新的客户端请求该Servlet时 一般不会再实例化该Servlet类 也就是有多个线程在使用这个实例 Servlet容器会自动使用线程池等技术来支持系统的运行 如图 所示    >   >    这样 当两个或多个线程同时访问同一个Servlet时 可能会发生多个线程同时访问同一资源的情况 数据可能会变得不一致 所以在用Servlet构建的Web应用时如果不注意线程安全的问题 会使所写的Servlet程序有难以发现的错误      Servlet的线程安全问题    Servlet的线程安全问题主要是由于实例变量使用不当而引起的 这里以一个现实的例子来说明     Import javax servlet *;  Import javax servlet *;  Import java io *;  Public class Concurrent Test extends HttpServlet PrintWriter output;  Public void service (HttpServletRequest request   HttpServletResponse response) throws ServletException IOException String username;  Response setContentType ( text/; charset=gb );  Username = request getParameter ( username );  Output = response getWriter ();  Try Thread sleep ( ); //为了突出并发问题 在这设置一个延时   Catch (Interrupted Exception e)  output println( 用户名: +Username+ <BR> );        该Servlet中定义了一个实例变量output 在service方法将其赋值为用户的输出 当一个用户访问该Servlet时 程序会正常的运行 但当多个用户并发访问时 就可能会出现其它用户的信息显示在另外一些用户的浏览器上的问题 这是一个严重的问题 为了突出并发问题 便于测试 观察 我们在回显用户信息时执行了一个延时的操作 假设已在web xml配置文件中注册了该Servlet 现有两个用户a和b同时访问该Servlet(可以启动两个IE浏览器 或者在两台机器上同时访问) 即同时在浏览器中输入     a //localhost: /servlet/ConcurrentTest? Username=a    b //localhost: /servlet/ConcurrentTest? Username=b    如果用户b比用户a回车的时间稍慢一点 将得到如图 所示的输出    >   >    从图 中可以看到 Web服务器启动了两个线程分别处理来自用户a和用户b的请求 但是在用户a的浏览器上却得到一个空白的屏幕 用户a的信息显示在用户b的浏览器上 该Servlet存在线程不安全问题 下面我们就从分析该实例的内存模型入手 观察不同时刻实例变量output的值来分析使该Servlet线程不安全的原因     Java的内存模型JMM(Java Memory Model)JMM主要是为了规定了线程和内存之间的一些关系 根据JMM的设计 系统存在一个主内存(Main Memory) Java中所有实例变量都储存在主存中 对于所有线程都是共享的 每条线程都有自己的工作内存(Working Memory) 工作内存由缓存和堆栈两部分组成 缓存中保存的是主存中变量的拷贝 缓存可能并不总和主存同步 也就是缓存中变量的修改可能没有立刻写到主存中 堆栈中保存的是线程的局部变量 线程之间无法相互直接访问堆栈中的变量 根据JMM 我们可以将论文中所讨论的Servlet实例的内存模型抽象为图 所示的模型    >   >    下面根据图 所示的内存模型 来分析当用户a和b的线程(简称为a线程 b线程)并发执行时 Servlet实例中所涉及变量的变化情况及线程的执行情况 如图 所示    >   >    从图 中可以清楚的看到 由于b线程对实例变量output的修改覆蓋了a线程对实例变量output的修改 从而导致了用户a的信息显示在了用户b的浏览器上 如果在a线程执行输出语句时 b线程对output的修改还没有刷新到主存 那么将不会出现图 所示的输出结果 因此这只是一种偶然现象 但这更增加了程序潜在的危险性 cha138/Article/program/Java/gj/201311/27302

相关参考

知识大全 Java语言深入 多线程程序模型研究

Java语言深入多线程程序模型研究  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  多线程是较复杂

知识大全 Java servlet多线程

Javaservlet多线程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Servlet体系结

知识大全 深入理解Java Servlet与Web容器之间的关系

深入理解JavaServlet与Web容器之间的关系  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

知识大全 Java线程知识深入解析

Java线程知识深入解析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一般来说我们把正在计算机

知识大全 Java多线程之ConcurrentHashMap深入分析

Java多线程之ConcurrentHashMap深入分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 Java多线程之volatile深入分析

Java多线程之volatile深入分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  vola

知识大全 Java线程控制权源代码的深入探讨

Java线程控制权源代码的深入探讨  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java线程控

知识大全 Java多线程(五)之BlockingQueue深入分析

Java多线程(五)之BlockingQueue深入分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 深入解析PHP中的(伪)多线程与多进程

深入解析PHP中的(伪)多线程与多进程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!本篇文章是对P

知识大全 破除java神话之原子操作都是线程安全的

  java中原子操作是线程安全的论调经常被提到根据定义原子操作是不会被打断地的操作因此被认为是线程安全的实际上有一些原子操作不一定是线程安全的    这个问题出现的原因是尽量减少在代码中同步关键字同