注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

0与1构筑世界,程序员创造时代

软件架构设计 Java编程

 
 
 

日志

 
 

Servlet的线程安全问题  

2008-11-16 22:25:31|  分类: Java |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
  文章声明

  
作者:
傲风(aofengblog@163.com)       编写时间:2008年11月16日

网址:http://aofengblog.blog.163.com



        因为架构调整修改一个应用,我在检查QA做压力测试生成的应用日志时,发现一些数据不对劲,于是就开始了三天多的问题排查,从WEB容器 --> 缓存服务器 --> 新增加的代码 --> 压力测试工具,最后找到问题的根源:应用中一个旧的Servlet的代码存在线程安全的BUG。
        下面就写一个简单的示例代码来演示一下Servlet的线程安全问题。

一、源代码。

package cn.aofeng.thread;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


/**

 * 一个非线程安全的Servlet演示:<br/>

 * 变量<code>name</code><code>desc</code>被定义成实例变量。

 * 

 * @author aofeng <a href="mailto:aofengblog@163.com>aofengblog@163.com</a>

 */

public class NotSafeThreadServlet extends HttpServlet {


  private static final long serialVersionUID = -2646458389304935967L;

   private String name;

   private String desc;


   public NotSafeThreadServlet() {

     super();

   }

  /**

   * The doGet method of the servlet. <br>

   * @param request the request send by the client to the server

   * @param response the response send by the server to the client

   * @throws ServletException if an error occurred

   * @throws IOException if an error occurred

   */

   public void doGet(HttpServletRequest request,

           HttpServletResponse response)

       throws ServletException, IOException {

            

             // 接收参数

     String paramName = request.getParameter("name");

     String paramDesc = request.getParameter("desc");


             // 赋值

     name = paramName;

     desc = paramDesc;


             // 休眠

     try {

       Thread.sleep(3000);

     catch (InterruptedException e) {

       e.printStackTrace();

     }


             // 输出响应

     response.setContentType("text/html");

     PrintWriter out = response.getWriter();

     out.println("<HTML>");

     out.println("  <HEAD><TITLE>NotSafeThreadServlet</TITLE></HEAD>");

     out.println("  <BODY>");

     out.print("    This is [");

     out.print(this.toString());

     out.println("], using the GET/POST method");

     out.print("<br/>paramName=" + paramName);

     out.print("paramDesc=" + paramDesc);

     out.print("<br/>name=" + name);

     out.print("desc=" + desc);

     out.println("  </BODY>");

     out.println("</HTML>");

     out.flush();

     out.close();

   }


   public void doPost(HttpServletRequest request,

        HttpServletResponse response)

       throws ServletException, IOException {

     doGet(request, response);

   }

}



二、运行演示。
在两个打开的浏览器上,同时进行请求:

1、第一个浏览器。
    请求URL:http://192.168.228.1:8080/AntTest/servlet/NotSafeThreadServlet?name=111&desc=desc_1111
    响应结果如下:
   
Servlet线程安全 - 傲风 - 傲风的博客



2、第二个浏览器。
    请求URL:http://192.168.228.1:8080/AntTest/servlet/NotSafeThreadServlet?name=222&desc=desc_2222
   
响应结果如下:
   
Servlet线程安全 - 傲风 - 傲风的博客

从以上的结果可以看出,第二个请求覆盖了第一个请求给实例变量name和desc赋的值。


<正文结束>
  评论这张
 
阅读(624)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017