将具有 bean 并发性的单例会话 bean 投入服务时的容器保证
Container guarantees when putting a singleton session bean with bean concurrency into service
我有以下代码:
@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 managed concurrency
直接问题:我是否需要同步 threadSafeObject 的初始化以及所有其他对它的访问以防止可能的可见性问题,例如线程 A 处理 bean 的初始化,但之后,线程 B 没有看到正确的 threadSafeObject 视图?
更详细的问题:当将单例会话 bean 投入服务时,在 bean 管理并发的情况下,容器是否提供关于状态安全发布的任何保证单例会话bean 的? EJB 规范 [我阅读的部分] 对此没有给出任何提示。
更多来自我的部分:对于容器管理的并发,容器同步所有对单例会话 bean 的访问,因此我们可以保证所有线程看到最新的一致豆的状态。对于 bean 管理的并发,我一直读到所有的同步都留给了 bean 的实现者,故事到此结束。而已。因此,即使容器本身不执行同步,bean 初始化和向 bean 提供请求仍然是 container managed,我仍然希望容器以某种方式执行写入将 bean 投入使用时的障碍。例如,JVM 为实例初始化提供了这种保证,比喻说 JEE 容器是类固醇的 JVM,具有撕裂的 abs,对吗? :D
好问题!我认为这是规范的相关部分(采用 from here):
Independent of the bean’s concurrency management type, the container
must ensure that no concurrent access to the Singleton bean instance
occurs until after the instance has successfully completed its
initialization sequence, including any @PostConstruct lifecycle
callback method(s). The container must temporarily block any Singleton
access attempts that arrive while the Singleton is still initializing.
(第 4.8.5 节,第 109 页)
我对"no concurrent access"的理解是@PostConstruct 完成后需要进行一些容器同步。希望对您有所帮助?
我有以下代码:
@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 managed concurrency
直接问题:我是否需要同步 threadSafeObject 的初始化以及所有其他对它的访问以防止可能的可见性问题,例如线程 A 处理 bean 的初始化,但之后,线程 B 没有看到正确的 threadSafeObject 视图?
更详细的问题:当将单例会话 bean 投入服务时,在 bean 管理并发的情况下,容器是否提供关于状态安全发布的任何保证单例会话bean 的? EJB 规范 [我阅读的部分] 对此没有给出任何提示。
更多来自我的部分:对于容器管理的并发,容器同步所有对单例会话 bean 的访问,因此我们可以保证所有线程看到最新的一致豆的状态。对于 bean 管理的并发,我一直读到所有的同步都留给了 bean 的实现者,故事到此结束。而已。因此,即使容器本身不执行同步,bean 初始化和向 bean 提供请求仍然是 container managed,我仍然希望容器以某种方式执行写入将 bean 投入使用时的障碍。例如,JVM 为实例初始化提供了这种保证,比喻说 JEE 容器是类固醇的 JVM,具有撕裂的 abs,对吗? :D
好问题!我认为这是规范的相关部分(采用 from here):
Independent of the bean’s concurrency management type, the container must ensure that no concurrent access to the Singleton bean instance occurs until after the instance has successfully completed its initialization sequence, including any @PostConstruct lifecycle callback method(s). The container must temporarily block any Singleton access attempts that arrive while the Singleton is still initializing.
(第 4.8.5 节,第 109 页)
我对"no concurrent access"的理解是@PostConstruct 完成后需要进行一些容器同步。希望对您有所帮助?