Java servlet中的线程

Java servlet中的线程,java,multithreading,servlets,Java,Multithreading,Servlets,在应用程序中,如果涉及多个servlet,那么每次都会为不同的servlet创建一个新线程 例如,我有两个servlet Servlet1和Servlet2都是从同一个html表单获取rquest,一个是通过锚标记获取,另一个是通过表单获取 当点击链接时,请求被发送到servlet 1,servlet 1再次将请求发送到索引页面,并从那里提交表单,请求被发送到servlet 2 那么,是为servlet 1和servlet 2分别创建了两个线程,还是只创建了一个为这两个servlet提供服务的线

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

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

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


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

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

当请求到达servlet容器(例如:Tomcat,WAS)时,它通常从线程池中随机选取一个线程,接收到的请求将由所选线程在整个请求生命周期内处理。换句话说,从UI层到服务层再到数据层执行相同的线程。而且,即使单击同一链接,该链接又将请求提交给同一个servlet,也不能保证在后续请求中分配相同的线程。也就是说,在即时请求中,容器可能会拾取相同的线程

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

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

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

例如,我有两个servlet servlet 1和servlet 2都得到了 rquest来自同一个html表单,一个是通过锚标记和 另一个通过表格

提交
表单时,浏览器会发送HTTP请求。您的服务器将调度一个
线程来处理它。想象一下它在做这样的事情(实际上要复杂得多)

同样,如果您遵循锚定链接,浏览器将发送一个新的HTTP请求,并以相同的方式进行处理

Servlet
类实例在线程之间共享

  • 每个http请求都在一个单独的线程中处理,因为创建线程会增加一些开销,所以服务器会维护一个线程池,当请求传入时,它们只会重用一个空闲线程来服务该请求
  • 如果在一个servlet中创建会话并设置会话属性,那么对于该会话,可以在任何其他servlet中访问该会话属性

  • 谢谢你的回复,servlet是基于web.xml中的load on startup值加载并在此之后实例化的,但如果未提供该值,则在收到第一个请求时加载并实例化该值,并且初始化时只执行一次init方法。不应将全局varibale类会话或请求数据作为servlet实例,因为它将由用户共享所有线程。对于每个新请求,都会创建一个新线程。我问的是,在我上面描述的情况下会发生什么。对于您的情况,它是一个新请求,因此将由线程处理。实际上,我使用eclipse ide构建了这个程序,我在两个servlet上都显示了线程名称,它给出了相同的值。这是否意味着为一个会话创建了一个线程,并用于为特定会话中涉及的所有servlet提供服务?不!您可能还希望尝试将线程休眠一段时间,并在前一个请求(或线程)唤醒之前从另一个窗口提交新的请求。顺便提一下您正在使用哪个应用程序服务器?@Sotirious感谢您的回复事实上我使用eclipse ide构建了该程序,我在两个servlet上显示了线程名称,它给出了相同的值。这是否意味着为一个会话创建了一个线程,并用于为特定会话中涉及的所有servlet提供服务???@anubhav,这是因为Servlet容器正在使用
    线程
    池。当请求传入时,从池中获取一个
    线程来处理它。当请求完成并返回响应时,
    线程
    将返回到池中,并可用于将来的请求。它与http会话无关,也与涉及哪个
    Servlet
    无关。因此,这意味着有可能使用同一线程为另一个Servlet提供服务??但是对于所有servlet,一个请求将有一个会话,这样就可以在另一个servlet中使用一个servlet中设置的会话属性。@anubhav对于每个请求,容器将创建
    HttpServletRequest
    (可能绑定到
    HttpSession
    对象)和
    HttpServletResponse
    对象。这些将提供给正在处理
    线程中使用的servlet。这是从你那里抽象出来的。您通常只需要关心servlet。
    线程
    实例可用于处理任何servlet的任何请求。好的,感谢您的帮助并消除我的疑虑,我想知道我的上述评论是否意味着同一线程有可能被用于服务另一个servlet??但是对于所有的servlet,一个请求将有一个会话,这样就可以在另一个servlet中使用一个servlet中设置的会话属性是否正确。谢谢!!!
    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();