最近在看线程的有关知识,碰到一个小问题,目前还没有解决,现记录下来。



如果在我们自己写的servlet里有成员变量,因为多线程的访问就会出现一些线程问题。这点大家都知道,我们看下面的例子。

public class ConcurrentTest extends HttpServlet {
    PrintWriter output;
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String  username;
        response.setContentType("text/html;charset=gb2312");
        username=request.getParameter("Username");
        output=response.getWriter();
        try {
            //为了突出并发问题,在这设置一个延时
            Thread.sleep(5000);
            output.println("用户名:"+username+"<BR>");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

部署在tomcat7上

然后我们在浏览器上发两个链接。

  a: http://localhost:8080/ServletTest/ConcurrentTest?Username=a

  b: http://localhost:8080/ServletTest/ConcurrentTest?Username=b

当a发送后,过半秒后发送b。

我们可以看到a请求的返回页是什么都没有

而b上显示

用户名:a

用户名:b



为什么会有这个效果是因为,a请求的output这个变量在多线程的情况下被b线程的output覆盖了。所以"两个"(其实只有一个)servlet的输出流对象都定位到b上面了。



这是一个经典的例子。

再看下面这个。

public class SimpleServlet extends HttpServlet{
       // A variable that is NOT thread-safe!
       private int counter = 0;
       public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doPost(req, resp);
       }

       public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
       {
              resp.getWriter().println("<HTML><BODY>");
              resp.getWriter().println(this + " ==> ");
              resp.getWriter().println(Thread.currentThread() + ": <br>");
              for (int c = 0; c < 10; c++){
                     resp.getWriter().println("Counter = " + counter + "<BR>");
                     try {
                            Thread.sleep((long) Math.random() * 1000);
                            counter++;
                     }
                     catch (InterruptedException exc){}
              }
              resp.getWriter().println("</BODY></HTML>");
       }
}

和第一个例子似乎差不多,只是变量由PrintWriter变成了int。

我们在做三个请求。

    <HTML>  

    <BODY>  

    <TABLE>
        <TR>
            <TD><IFRAME src="./SimpleServlet" name="servlet1" height="200%"> </IFRAME></TD>
        </TR>
        <TR>
            <TD><IFRAME src="./SimpleServlet" name="servlet2" height="200%"> </IFRAME></TD>
        </TR>
        <TR>
            <TD><IFRAME src="./SimpleServlet" name="servlet3" height="200%"> </IFRAME></TD>
        </TR>
    </TABLE>
    </BODY>
    </HTML>  

在tomcat7下 结果是

com.zwchen.servlet.SimpleServlet@109da93:

Counter = 0

Counter = 1

Counter = 2

Counter = 3

Counter = 4

Counter = 5

Counter = 6

Counter = 7

Counter = 8

Counter = 9





com.zwchen.servlet.SimpleServlet@109da93:

Counter = 10

Counter = 11

Counter = 12

Counter = 13

Counter = 14

Counter = 15

Counter = 16

Counter = 17

Counter = 18

Counter = 19



com.zwchen.servlet.SimpleServlet@109da93:

Counter = 20

Counter = 21

Counter = 22

Counter = 23

Counter = 24

Counter = 25

Counter = 26

Counter = 27

Counter = 28

Counter = 29

并没有出现我们想象中的乱序问题。



一种解释是tomcat7中使用了ThreadPoolExecutor技术。

但是我依然不明白,那为什么同是在tomcat7下,第一个例子就会出现覆写的问题呢?

这个问题,估计的看源码才行。

如果有哪位大侠知道问题的答案请告诉我,跪谢了。

感谢glt

参考资料

两个例子分别来自下面两个地址 详细信息大家自己去看看吧

http://www.cnblogs.com/gw811/archive/2012/09/07/2674859.html

http://zwchen.iteye.com/blog/91088

tomcat中的线程问题2的更多相关文章

  1. tomcat中的线程问题

    看这篇文章之前,请先阅读: how tomcat works 读书笔记 十一 StandWrapper 上 地址如下: http://blog.csdn.net/dlf123321/article/d ...

  2. Tomcat中常见线程说明

    http://blog.csdn.NET/jeff_fangji/article/details/41786205 本文讲述了Tomcat的常见线程的功能.名称.线程池和配置等信息,其中源码来自于To ...

  3. Tomcat中的线程池StandardThreadExecutor

    之所以今天讨论它,因为在motan的的NettyServer中利用它这个线程池可以作为业务线程池,它定制了一个自己的线程池.当然还是基于jdk中的ThreadExecutor中的构造方法和execut ...

  4. 详解tomcat连接数和线程数

    前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...

  5. Tomcat 连接数与线程池详解

    前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...

  6. Tomcat中JVM内存溢出及合理配置及maxThreads如何配置(转)

    来源:http://www.tot.name/html/20150530/20150530102930.htm Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个Java虚 ...

  7. e.Tomcat中的sendfile支持

    sendfile实质是linux系统中一项优化技术,用以发送文件和网络通信时,减少用户态空间与磁盘倒换数据,而直接在内核级做数据拷贝,这项技术是linux2.4之后就有的,现在已经很普遍的用在了C的网 ...

  8. tomcat中server.xml配置详解

    Tomcat Server的结构图如下: 该文件描述了如何启动Tomcat Server <Server>     <Listener />     <GlobaNami ...

  9. How Tomcat works — 八、tomcat中的session管理

    在使用shiro的session的时候感觉对于tomcat中session的管理还不是特别清楚,而且session管理作为tomcat中比较重要的一部分还是很有必要学习的. 目录 概述 session ...

随机推荐

  1. Python descriptor

    class A: def __init__(self, name): self.name = name def __get__(self, ins, cls): print('call get') i ...

  2. VisualStudio2010配置OpenCV的一种一劳永逸的方法

    用VS使用OpenCV的时候,又不想全局配置,每次都要配置简直烦死了. 鉴于此,给大家介绍一种简便一点的方法. 配置环境的前提是:成功安装了OpenCV合适的版本. 我这里用的是OpenCV2.4.9 ...

  3. java之IO流详解(二)

    好了,昨天讲了字节流,现在我们就来讲字符流吧... 字符流可以这样理解,字符流 = 字节流 + 编码表,目的是为了更好的操作中文字符(注:字符流只可以可以操作字符类型的文件,不能操作影音图像文件,要操 ...

  4. Struts 2 之校验器

    对于输入校验,Struts2提供了两种方式,1.使用validate方法:2.基于XML配置实现 . validate()方法 支持校验的Action必须实现Validateable接口,一般直接继承 ...

  5. cassandra 如何写数据以及放置副本

    application发送数据到server application 发送请求到server 根据设置的load balance 规则从cluster中挑选一个coordinator,一般使用轮询即可 ...

  6. 百度地图SDK3.4的使用

    使用过百度地图的开发者应该都知道原始百度地图的开发的基本流程,但是随着百度地图的更新,百度地图的api有了翻天覆地的变化,最新版本的sdk为v3.4 2015年4月14日上线,优化了许多接口的设计,简 ...

  7. javascript之类型转换

    JavaScript是一种无类型语言,但同时JavaScript提供了一种灵活的自动类型转换的处理方式.基本规则是,如果某个类型的值用于需要其他类型的值的环境中,JavaScript就自动将这个值转换 ...

  8. ROS(indigo)ABB机器人MoveIt例子

    ROS(indigo)ABB机器人例子 参考网址: 1  http://wiki.ros.org/Industrial 2  http://wiki.ros.org/abb 3  https://gi ...

  9. 为何写flash的时候要地址左移一位?

    代码一: #define Writeflash(addr,dat) *((volatile INT16U *)(addr<<1))=(INT16U)dat #define Readflas ...

  10. TSVN客户端复制文件

    TSVN客户端复制文件 代码重构中,可能需要将一个大文件拆分成2个小文件,同时要保证拆分后的小文件继承原来的SVN历史记录. TSVN客户端只有Rename功能,没有Copy功能. 可进入Browse ...