【问题标题】:How multithreading is handled in web containers [duplicate]Web容器中如何处理多线程[重复]
【发布时间】:2016-12-04 13:21:30
【问题描述】:
我所知道的
Web 容器为每个请求创建一个新线程。
我不知道的事
是否为每个请求创建了新的 servlet 对象?
我问这个的原因是想了解如果同一个 servlet 对象用于多个请求,线程同步问题会如何发生。如果 Web 容器为每个新请求创建一个新的 servlet 对象,那么我不会看到一个问题。但是如果它使用同一个 servlet 对象来服务多个请求,就会发生同步问题。
这是如何在典型的 java web 容器中处理的?
【问题讨论】:
标签:
java
multithreading
servlets
【解决方案1】:
Web 容器为每个请求创建一个新线程。
没有。它重用线程池中的线程。
是否为每个请求创建了新的 servlet 对象?
没有。 servlet 是一个单例。每个 Web 应用程序仅创建一个实例。您的 servlet 必须是线程安全的,因为它由多个线程同时调用。但这通常很容易,因为 servlet 通常是无状态的。
【解决方案2】:
是否为每个请求创建了新的 servlet 对象?
默认情况下,Servlet 容器会创建一个单独的 servlet 实例,并将用于在单独的线程中处理所有请求。因此,请确保您的 servlet 类是线程安全的(即,您的 servlet 类不应将任何有状态数据作为实例变量等)。
除此之外,Servlet 容器在容器启动期间或在收到第一个请求时创建 servlet 实例。
您可以通过在web.xml 或@WebServlet(urlPatterns="/xyz", loadOnStartup=1)) 中指定load-on-startup 来强制容器创建servlet 实例。
通常最好使用load-on-startup 加载servlet(除非您有任何特殊要求),这样第一个请求就不会影响性能。
【解决方案3】:
一般意义上的 servlet 是单例,但是如果您将同一个 servlet 类映射到使用不同名称的不同 URL 映射,那么您将拥有相同 servlet 的许多实例。
大多数 servlet 是无状态的,如果您确实使它们成为有状态的,那么要非常小心共享可变性。
早期的 servlet API 曾经有 SingleThreadModel 接口在一个时间点强加单线程访问,这样你一次只能服务一个请求,但是我看到这个接口在最近的 API 中被弃用了,因为它不能解决并发问题完全像静态变量等。