为了账号安全,请及时绑定邮箱和手机立即绑定

servlet的每个实例与servlet中的每个servlet线程之间的区别?

servlet的每个实例与servlet中的每个servlet线程之间的区别?

撒科打诨 2019-09-18 14:59:37
是否有多个servlet类实例?当我听到“servlet的每个实例”时,任何人都可以详细说明吗?
查看完整描述

3 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

当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 (Entry<String, HttpServlet> entry : 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()。


您看,servletcontainer 为每个请求重用相同的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.

    } 

}


查看完整回答
反对 回复 2019-09-18
?
心有法竹

TA贡献1866条经验 获得超5个赞

不,只有一个servlet实例可以重用于来自多个客户端的多个请求。这导致两个重要规则:

  • 不要在servlet中使用实例变量,除了应用程序范围的值,通常从上下文参数中获取。

  • 不要synchronized在servlet中创建方法

(同样适用于servlet过滤器和jsps)


查看完整回答
反对 回复 2019-09-18
?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

虽然已经有一些很好的答案,但没有一个人谈到在分布式环境中部署的Java Web应用程序。这是一个实际场景,其中实际创建了单个servlet的多个实例。在分布式环境中,您有一组机器来处理请求,请求可以转到任何这些机器。这些机器中的每一台都应该能够处理请求,因此每台机器都应该在其JVM中有一个MyAwesomeServlet实例。

因此,正确的说法是每个servlet只有一个实例,除非它实现了SingleThreadModel。

SingleThreadModel简单地说每个Servlet实例只需要一个线程,所以基本上你需要为每个处理它的请求创建一个实例,这基本上会杀死以并行方式处理请求的整个概念而不是因为servlet对象创建和初始化在准备好处理请求之前占用了时间,所以这被认为是一种很好的做法。



查看完整回答
反对 回复 2019-09-18
  • 3 回答
  • 0 关注
  • 488 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信