在servlets中,每个servlet实例与每个servlet线程之间的区别是什么?
在servlets中,每个servlet实例与每个servlet线程之间的区别是什么?
这个问题已经有答案了:
Servlet类有多个实例吗?我听说\"每个Servlet实例\"
有人能详细解释一下吗?
admin 更改状态以发布 2023年5月21日
当Servlet容器启动时,它会:
- 读取
web.xml
; - 在类路径中找到声明的Servlet;以及
- 仅加载和创建每个Servlet一次。
大致就像这样:
String urlPattern = parseWebXmlAndRetrieveServletUrlPattern(); String servletClass = parseWebXmlAndRetrieveServletClass(); HttpServlet servlet = (HttpServlet) Class.forName(servletClass).newInstance(); servlet.init(); servlets.put(urlPattern, servlet); // Similar to a map interface.
这些Servlet被存储在内存中,并在请求URL与Servlet的关联url-pattern
匹配时被重用。然后,servlet容器执行类似于以下代码:
for (Entryentry : servlets.entrySet()) { String urlPattern = entry.getKey(); HttpServlet servlet = entry.getValue(); if (request.getRequestURL().matches(urlPattern)) { servlet.service(request, response); break; } }
然后,GenericServlet#service()
决定调用哪个doGet()
、doPost()
等方法,基于HttpServletRequest#getMethod()
。
你看,Servlet容器为每个请求重用相同的Servlet实例。换句话说:servlet在每个请求中是共享的。这就是为什么编写Servlet代码线程安全非常重要的原因-这实际上很简单:只需将请求或会话范围的数据分配为方法局部变量,而不是Servlet实例变量。例如:
public class MyServlet extends HttpServlet { private Object thisIsNOTThreadSafe; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Object thisIsThreadSafe; thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests! thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe. } }