首页 » Tomcat » 正文

Tomcat容器中的用户和线程

今天一个之前的同事问我是不是Tomcat容器中每个用户的各种操作都会在同一个线程中执行,例如,一个用户上来做了一个订单,待会又做支付,是不是应该在同一个线程中完成的,之前同事说他们要做用户的行为分析,他的同事说是这样的,并且查看了下日志,还真是这样的。

第一直觉就是感觉不是这样的,Tomcat容器使用的是一个线程池,一个请求是由一个线程处理的,但是同一个用户的不同请求不确定分配到哪个线程,然而,我忽然想到Tomcat 6 以前的BIO,当一个Socket链接以后,就分配一个线程,这个线程一直服务到Socket关闭,而且,HTTP 1.1支持长链接,也就是不同请求之间使用的是一个Socket,这样想来,同一个用户的不同请求使用同一个线程也是可能的。

然后,我让前同事查看了一下,使用的Tomcat7, 并且查看server.xml文件,发现使用的是NIO。于是,这个想法就破灭了。

为了证明我的第一想法是对的,我做了一个简单的实验:

我写了一个JSP程序:

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="com.robert.Test"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%=new Test().test(request.getSession(true)) %>
</body>
</html>

在JSP里面创建了一个Session,也就是代表一个用户登录。

然后,在Java中返回线程 ID和Session ID。

1
2
3
4
5
6
7
8
9
package com.robert;

import javax.servlet.http.HttpSession;

public class Test {
    public String test(HttpSession session) {
        return Thread.currentThread().getId() + ":" + session.getId();
    }
}

结果证明,线程是不可能被一个用户重用的。

 35:C7F67115EA5EF49BAA9320160C5F3301 
 36:C7F67115EA5EF49BAA9320160C5F3301 
 37:C7F67115EA5EF49BAA9320160C5F3301 

可见,同一个session使用的是不同的线程ID。

示例代码: ThreadTestWeb