当我们想要有条件地初始化 bean 的某些字段时,使用后构造方法,我们是否需要关心字段的波动性,因为它是多线程环境?
比如说,我们有这样的东西:
@ApplicationScoped
public class FooService {
private final ConfigurationService configurationService;
private FooBean fooBean;
@Inject
FooService(ConfigurationService configurationService) {
this.configurationService = configurationService;
}
void init(@Observes @Initialized(ApplicationScoped.class) Object ignored) {
if (configurationService.isFooBeanInitialisationEnabled()) {
fooBean = initialiseFooBean(configurationService); // some initialisation
}
}
void cleanup(@Observes @Destroyed(ApplicationScoped.class) Object ignored) {
if (fooBean != null) {
fooBean.cleanup();
}
}
}
所以应该fooBean
比方说,被包裹在AtomicReference
或成为volatile
或者这将是多余的额外保护?
P.S.在这种特殊情况下,它可以重新表述为:构建后事件和销毁后事件是否由同一线程执行?不过,我想得到一个更一般情况的答案。
我想说这取决于哪个线程实际启动和销毁上下文。
如果您使用常规事件,它们是同步的(异步事件已在 CDI 2.0 中添加)ObservesAsync
, see
Java EE 8:使用 ManagedExecutorService 发送异步 CDI 2.0 事件 http://www.adam-bien.com/roller/abien/entry/java_ee_8_sending_asynchronous),因此它们在与调用者相同的线程中被调用。
一般来说,我不认为使用相同的线程(在应用程序服务器或独立应用程序中),所以我建议使用volatile
确保看到正确的值(基本上是在销毁线程上看到的构造值)。然而,以并发方式启动和销毁应用程序并不是一个经常发生的用例......
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)