【问题标题】:Singleton Servlet instance单例 Servlet 实例
【发布时间】:2015-12-15 16:06:47
【问题描述】:

Tomcat 将 servlet 作为一个单例对象,然后,将此单例对象引用设置为连接线程作为局部变量。之后,每个线程也将这个局部变量作为同步播放。这样对吗?

我糊涂了,因为servlet是单例的,所以只有一个实例。但是规范说“不要将 service() 方法标记为同步,因为当时 servlet 容器不能使用实例池的方法。

Pool 和 singleton,细节上很混乱。容器是否使用“volatile”关键字来保持共享的本地变量在其池中相等?

【问题讨论】:

    标签: java servlets jakarta-ee


    【解决方案1】:

    servlet 是一个单例。这意味着对该 servlet 的每个请求都会调用该单个唯一对象的 service() 方法。

    因此使service() 方法同步可以正常工作,除非没有两个请求能够同时执行service() 方法:这就是同步的作用。

    因此,现在不是让 10 个用户同时执行该方法,而是让 1 个用户执行它,另外 9 个用户等待该方法返回,然后下一个执行该方法,而其他 8 个用户等待,等等. 因此,如果您有并发请求,它将使 servlet 非常慢,并且会未充分利用您的 Web 服务器的资源。

    因此,简而言之,您的 servlet 必须是线程安全的:它必须允许以安全的方式并发执行方法。

    【讨论】:

    • 好吧 Servlet 是一个单例,所以只有一个。但是为什么 servlet 规范说“实例池方法”?为什么容器需要一个实例的池?
    • 如果服务器正在使用一个(即许多)servlet 实例池而不是一个,那么使方法同步将不是问题:每个请求都将使用池中自己的 servlet 实例。但它不使用池。因此,您不应该使方法同步。
    • 即使容器中只有一个实例,servlet容器在幕后让实例不止一个。
    • 如果是这样,它就不再是单例了。
    • 如果,容器所在的电脑有5个处理器,也只做一个实例呢?
    猜你喜欢
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2012-10-20
    • 2014-04-07
    • 1970-01-01
    • 2016-04-03
    相关资源
    最近更新 更多