向理解servlets和多线程的方向靠拢
向理解servlets和多线程的方向靠拢
我读了这个很棒的帖子:在Servlet中,每个实例和每个线程之间有什么区别? 它说\"Servlet容器对于每个请求重用同一个servlet实例。\"\n所以假设我们有一个servlet:\n
public class MyServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Object thisIsThreadSafe; thisIsThreadSafe = request.getParameter("foo"); // OK, 这是线程安全的。 } }
\n那么servlet容器在初始化时会内部调用:\n
MyServlet myServlet = new MyServlet(....);
\n然后当请求匹配web.xml中的内容时,它将返回这个实例myServlet。\n我需要帮助理解的是,当调用:\n
myServlet.doGet(..)
\n当只有一个实例时,多线程是如何工作的?这与servlet并不特定,我只是无法理解它是如何工作的。\n假设有10个并发用户在同一时间访问这个相同的servlet,这个实例在它们之间是共享的,为什么它不会阻塞并以串行方式工作,它是如何并发执行的?
本文主要讨论了Servlets和多线程的关系以及出现的问题和解决方法。
Java语言和虚拟机(VM)支持多个线程调用单个方法。每个线程都有自己的方法局部变量。如果想限制这一点,可以在方法中添加synchronized锁,或者让servlet实现SingleThreadModel接口(已被弃用)。但是,如果编写的servlet方法是线程安全的(即不将请求/会话范围的数据分配为实例变量),则不需要这样做。
多线程的关键点是虚拟机创建了一个单一实例,但每个调用这个共享实例的线程都会创建方法局部变量。方法局部变量实际上存储在线程中,而不是实例中。当线程离开方法时,这些变量将被销毁。
要进一步了解多线程的工作原理,可以查看我回答中提供的supports链接。这是最权威的解释。
总结起来,Servlets和多线程之间的关系是Java语言和虚拟机的特性所导致的。为了解决可能出现的多线程问题,可以使用synchronized锁或SingleThreadModel接口。但是,在编写servlet方法时,遵循线程安全的编程规范(不将请求/会话范围的数据分配为实例变量)是更好的做法。