Java中的无状态bean在两次来自客户端的调用之间不保留其状态。因此,简而言之,我们可以将它们视为具有业务方法的对象。每个方法接受参数并返回结果。当调用该方法时,在执行堆栈中创建一些局部变量。当该方法返回时,局部变量从堆栈中删除,并且如果分配了一些临时对象,则会进行垃圾回收。
在我看来,这与通过单独的线程调用同一单个实例的方法没有区别。那么,为什么容器不能使用一个bean实例而不是池化多个bean呢?
Java中的无状态bean在两次来自客户端的调用之间不保留其状态。因此,简而言之,我们可以将它们视为具有业务方法的对象。每个方法接受参数并返回结果。当调用该方法时,在执行堆栈中创建一些局部变量。当该方法返回时,局部变量从堆栈中删除,并且如果分配了一些临时对象,则会进行垃圾回收。
在我看来,这与通过单独的线程调用同一单个实例的方法没有区别。那么,为什么容器不能使用一个bean实例而不是池化多个bean呢?
对象池有几个作用。
首先,通过每个实例只有一个bean,您可以确保线程安全(例如Servlets不是线程安全的)。
其次,您可以减少bean可能具有的任何潜在启动时间。虽然Session Beans是“无状态”的,但它们只需要与客户端无关的无状态。例如,在EJB中,您可以将多个服务器资源注入到Session Bean中。该状态对bean是私有的,但没有理由从调用到调用保留该状态。因此,通过汇集bean,您将仅在创建bean时减少这些查找。
第三,您可以使用bean池作为限流的一种手段。如果池中只有10个Bean,则最多只会有10个请求同时工作,其余请求将排队等待。
池化提高性能。
一个单一实例处理所有请求/线程将导致很多争用和阻塞。
由于您不知道将使用哪个实例(并且几个线程可以同时使用单个实例),因此bean必须是线程安全的。
容器可以根据实际活动管理池大小。
方法本质上是线程安全的(包括静态方法)。为什么?很简单,因为方法内部的每个变量都是在堆栈内存中创建的,即方法内部使用的每个变量都是每次调用时创建的(它不是共享的)。但是,参数不属于堆栈。
然而,如果方法使用了不安全的变量,则该方法是不安全的:
a)调用静态字段或变量。但是,在每种情况下都会发生这种情况。
b)调用共享资源。例如EntityManager。
c)传递不安全的参数。