0

在应用程序中,如果涉及多个 servlet,那么每次为不同的 servlet 创建一个新线程时

例如,我有 2 个 servlet servlet 1 和 servlet 2 都从同一个 html 表单中获取 rquest 一个是通过锚标记,另一个是通过表单

当点击链接时,请求被发送到 servlet 1,它再次将请求分派到索引页面,然后从那里提交表单,请求被发送到 servlet 2

那么是为 servlet 1 和 servlet 2 分别创建了 2 个线程,还是只创建了 1 个为两个 servlet 服务的线程?

4

4 回答 4

6

Servlet 容器的一般模式是使用一个Thread来处理一个请求。

例如,我有 2 个 servlet servlet 1 和 servlet 2 都从同一个 html 表单中获取 rquest 一个是通过锚标记,另一个是通过表单

当您提交 时form,浏览器会发送一个 HTTP 请求。您的服务器调度 aThread来处理它。想想它做这样的事情(实际上要复杂得多)

final Servlet servlet = ...// which servlet is url-mapped to the request
Runnable toRun = new Runnable(
    public void run() {
        servlet.service(request, response); // with exception handling of course
    }
);
Thread toDispatch = new Thread(toRun); // actually get it from pool, but for simplicity
toDispatch.start();

同样,如果您跟随锚链接,您的浏览器会发送一个新的 HTTP 请求,该请求将以相同的方式处理。

Servlet实例在线程之间共享。

于 2013-09-22T14:47:49.373 回答
3

当一个请求到达 Servlet Container(例如:Tomcat、WAS)时,它通常会从 ThreadPool 中随机选取一个线程,在整个请求生命周期中,接收到的请求将由所选线程处理。换句话说,从 UI 层到服务层再到数据层执行相同的线程。并且不能保证在随后的请求中分配相同的线程,即使您单击相同的链接反过来将请求提交给相同的 servlet。据说在立即请求中,Container 可能会选择相同的线程。

如果要测试,请在 Servlet 中打印线程名称并多次提交请求。在您的示例中,多次单击锚链接并查看结果。

回答您的问题: 如上所述,首先,每次请求到达时都不会创建新线程。Servlet2 可能会使用相同的线程。

于 2013-09-22T14:46:25.380 回答
1

对 Web 服务器的每个请求都由线程池中的一个新线程提供服务。servlet 实例在请求之间共享,即线程。所以好的设计实践是在 servlet 中没有全局变量,否则会看到竞争条件。

于 2013-09-22T14:33:33.597 回答
0
  1. 每个 http 请求都在一个单独的线程中处理,并且创建线程会增加一些开销,因此服务器会维护一个线程池,并且当请求进入时,它们只是重用一个空闲线程来服务该请求。
  2. 如果您在一个 servlet 中创建会话并设置会话属性,那么对于该会话,可以在任何其他 servlet 中访问该会话属性。
于 2013-09-22T17:50:52.140 回答