Servlet单例多例问题

版权声明: https://blog.csdn.net/Dongguabai/article/details/83713714

Servlet到底是单例还是多例我们说了都不算,要看官方说明。

结论:

Servlet既可以是单例,又可以是多例。Servlet 如果是同一个 Web App 的话,定义多次就是多例。所以要看容器,不能一概而论。

先看Servlet 2.3规范:

可以看出当Servlet实现类实现了SingleThreadModel接⼝后,他就是属于线程安全的,即多例的(对于一个服务让SingleThreadModel接口实现,Servlet容器可以实例化多个实例来处理沉重的请求负载并序列化请求特定实例)。

可以先看看这个接口:

说的也很清楚,这个接口在Servlet 2.4之后已经是@deprecated了。也就是说在Servlet2.4以后是⽆ٞ法保证的。所以还是要确保容
器的情况。不能一概而论。目前来看Tomcat8.5还保留了这个实现,在Servlet 4.0规范中这个也还保留着:

之所以要淘汰掉SingleThreadModel,是因为它相当于把锁加到了service方法上,同步的范围太大了,所以后续规范希望用户自行控制,并且告诉Servlet对象默认不是线程安全的。

但是是不是这样就可以认为在Servlet 2.4以后,Servlet的实例就都是多例的,必须要考虑线程安全的问题?也不能这么说,Servlet是单例或者多例,是要看Servlet声明的情况,比如:

上图看出:同样的类,申明两次。就是两个实例。那么就是多例。 不过Servlet Web应⽤不允许同名。

这两个Servelt⼜可以映射到不同的url-pattern上去。所以证明了既可以是单例,也可以是多例。这样会不会认为单例才会有线程安全,多例完全是线程不安全的?

但是也不能这么说,线程安全的问题与Servlet的实例是单例还是多例没有关系。主要关键还是体现在实现类的⽅ٛ法。比如,⼀个Servlet Context即Servlet应⽤底层有⼀个Map,Key就是Servlet的名称,value则是Servlet的实例。假设上图中的EchoServlet类实现了SingleThreadModel接⼝,那么它很可能两个实例都是线程安全的。这⾥很有可能,但也是不确定的,具体的还是要亲⾃去实现⼀下。所以到底是单例还是多例,是线程安全还是不安全,不能一概而论。

猜你喜欢

转载自blog.csdn.net/Dongguabai/article/details/83713714