将具有bean并发性的单例会话bean放入服务

时间:2018-02-09 09:01:57

标签: java concurrency synchronization singleton ejb

我有以下代码

@ConcurrencyManagement(BEAN)
@Startup
@Singleton
public class MySingletonBean {

    private Object threadSafeObject;

    @PostConstruct
    private void init() {
        threadSafeObject = nonTrivialInitialization();
    }

    private void nonTrivialInitialization() {
        // something with other beans or container resources
    }

    public void accessObject() {
        threadSafeObject.performSomeThreadSafeOperation();
    }

}

情况如下

  • 同时访问threadSafeObject(显然)
  • threadSafeObject在内部关注自己的同步
  • threadSafeObject初始化并不简单,即它访问其他bean或资源,因此需要在容器管理代码内部执行@PostConstruct方法,而不是在对象实例化时进行字段初始化
  • bean托管并发是必需的,因为单例bean背后的实际业务代码可以从JEE环境和非托管环境执行。因此,首选统一处理同步,因此,bean管理并发

直接问题:我是否需要同步threadSafeObject的初始化以及因此对其进行的所有其他访问以防止可能的可见性问题,例如:线程A处理bean的初始化,但是,之后,线程B没有看到threadSafeObject的正确视图?

更详细的问题:将单例会话bean投入服务时,如果是bean管理的并发,容器是否提供有关安全发布单例会话bean状态的任何保证? EJB规范[我读到的部分]并没有给出任何暗示。

我的部分更多的咆哮:对于容器管理的并发,容器同步对单例会话bean的所有访问,因此我们保证所有线程都能看到bean的最新一致状态。对于bean管理并发,我一直在阅读所有同步都留给bean的实现者,故事就在那里结束。而已。所以,即使容器本身不执行同步,bean初始化和向bean提供请求仍然是容器管理,我仍然期望容器在放置时以某种方式执行写入屏障豆子投入使用。例如,JVM为实例初始化提供了这种保证,并且隐喻认为JEE容器是带有翻录abs的类固醇上的JVM,对吧? :d

1 个答案:

答案 0 :(得分:0)

好问题!我认为这是规范的相关部分(采用from here):

  

独立于bean的并发管理类型,即容器   必须确保没有对Singleton bean实例的并发访问   在实例成功完成之后才会发生   初始化序列,包括任何@PostConstruct生命周期   回调方法。容器必须暂时阻止任何Singleton   在Singleton仍在初始化时到达的访问尝试。

(第4.8.5节,第109页)

我对"没有并发访问的理解"将在@PostConstruct完成后需要一些容器同步。希望有帮助吗?