【问题标题】:EJB instance variables thread safetyEJB 实例变量线程安全
【发布时间】:2015-06-29 15:37:46
【问题描述】:

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

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

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

@Stateless
public class User implements UserHomeLocal, UserHomeRemote
{

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

更一般地说:由于依赖注入,池 bean 是否可以共享实例变量?

【问题讨论】:

    标签: java jpa ejb server


    【解决方案1】:

    EJB 规范说

    容器序列化对每个有状态和无状态会话的调用 豆实例。大多数容器将支持许多实例 会话 bean 并发执行;然而,每个实例只看到 方法调用的序列化序列。因此,有状态或 无状态会话 bean 不必编码为可重入的

    这意味着默认情况下它是线程安全的。不需要额外的努力。同时请注意,无状态 bean 应该是“无状态的”。

    无状态 bean 具有可变状态不是一个好主意。这只是灾难的秘诀。如果您需要在所有实例之间共享一个变量,它必须是一个静态变量。 EJB 规范restricts 使用静态可变变量(类级别变量,如跟踪对所有实例的所有请求的计数器)。基本上“读取或写入非最终静态字段”是受限制的。

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

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

    【讨论】:

    • 我根本不想在 bean 之间共享实例变量,在这种情况下我问的是每个 bean 是否会有不同的 EntityManager 实例。
    • 负面投票者,请注意评论 - 为什么?我会努力改进我的答案。
    • 不是我,我认为你应该得到 +1,甚至是最好的答案。如果您可以澄清一点,我在哪里可以阅读所有这些具体细节,例如“实体管理器或任何此类 Java EE 对象(例如对 Java Persistence 实体管理器或有状态会话 bean 的引用)将被共享并保证是线程-默认安全(在无状态下)”。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 2014-12-02
    相关资源
    最近更新 更多