EJB 实例变量线程安全

EJB instance variables thread safety

根据我的理解,无状态 EJB 线程安全来自
对同一 SLSB 的并发请求将由该特定 bean 的不同实例提供服务,每个实例都有自己的实例变量。

例如,如果无状态 ejb 具有实例变量,例如 int 计数器, 每个池化的 EJB 将使用不同的计数器变量。

同样适用于注入的变量,如下例所示:

@Stateless
public class User implements UserHomeLocal, UserHomeRemote
{

    @PersistenceContext(name="J2EE")
    private EntityManager manager;
}

更一般地说:在任何情况下,池化 bean 是否可以由于依赖注入而共享实例变量?

EJB 规范说

The container serializes calls to each stateful and stateless session bean instance. Most containers will support many instances of a session bean executing concurrently; however, each instance sees only a serialized sequence of method calls. Therefore, a stateful or stateless session bean does not have to be coded as reentrant

这意味着默认情况下它是线程安全的。无需额外努力。同时注意无状态bean应该是"state-less".

无状态 bean 具有可变状态不是一个好主意。那只是灾难的根源。如果您需要在所有实例之间共享一个变量,它需要是一个静态变量。 EJB 规范restricts 使用静态可变变量(class 级别变量就像一个计数器来跟踪对所有实例的所有请求)。基本上"read or write nonfinal static fields"被限制了。

因此,要使池 bean 共享一个实例变量,该变量应该是静态的,并且是最终的。如果您出于任何实施原因正在查找此内容,您可以查看 Singleton beans。一旦创建了单例 bean,就可以将其注入到会话 bean 中。但是我不确定这是否值得。

是的,实体管理器或任何此类 Java EE 对象(例如对 Java 持久性实体管理器或有状态会话 bean 的引用)将被共享并默认保证线程安全(在无国籍状态下)