【问题标题】:Class variable in EJB 3 is thread safe?EJB 3 中的类变量是线程安全的吗?
【发布时间】:2012-05-04 07:03:12
【问题描述】:

在servlet中,因为除了实现SingleThreadModel之外它是单例的。参考这篇文章https://www.fortify.com/vulncat/en/vulncat/java/singleton_member_field_race_condition.html

但在 EJB 3 中,我找不到类似的文档。并且因为容器将创建一个池来处理 EJB。我觉得class变量应该是安全的,对吗?

例如classVar1是一个类变量,我在构造函数中初始化它,稍后使用。在servlet中可能有问题,但是在EJB 3中应该没问题吧?

@Stateles
public class HelloBean implements Hello {

    ObjectXXX classVar1;

    public HelloBean() {
        ObjectXXX classVar1 = new ObjectXXX();
    }

    public String doHello(String message) {
        return message + classVar1.method1();
    }
}

另一个问题是注入到EJB的资源(即JPA中的EntityManager)应该是线程安全的吗?

【问题讨论】:

    标签: java thread-safety ejb


    【解决方案1】:

    容器必须只允许特定 EJB 实例中的 1 个线程,因此:每个方法只能由单个线程执行,并且您的变量是“安全的”(当您在构造函数或 @PostConstruct 方法中初始化它时)。

    然而,SLSB(无状态EJB)应该用于保持状态。 EJB 是池化的,因此您无法保证您将返回到同一个实例。 SFSB 就是为此目的而制定的。

    EntityManager 与 EJB 中的每个实例字段一样,都是线程安全的。

    然而,EntityManager 本身是线程安全的,不能在超过 1 个线程可以访问它的环境中使用(即在 Servlet 中)。在这种情况下应该使用EntityManagerFactory

    【讨论】:

    • 如果我错了,请纠正我,应用服务器注入到 ejb 的 EntityManager 是线程安全的,它实际上是一个代理。但是,这不适用于通过 @PersistenceContext 的 CDI bean
    • 是的,容器使用了 EntityManager 的代理,但我并没有完全通过 @PersistenceContext' 获得“CDI bean”。您是指使用@Inject@PersistenceContext EntityManager 将CDI bean 注入EJB 到CDI bean 中吗?
    • @Depeng 你有点不对。不保证实体管理器是线程安全的。它可能在特定的实现中,但不是必须的。无状态或有状态的 EJB 使得访问注入的实体管理器是安全的,因为这两个本身是线程安全的。
    猜你喜欢
    • 2013-04-01
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多