tomcat中的线程问题2

时间:2023-12-26 13:53:25

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



如果在我们自己写的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