我有一个关于在 CDI 管理的 JSF bean (RequestScoped) 中注入类的问题,以及这些注入的类在 RequestScope 期间是否是线程安全的。
也许最好先显示示例代码:
----------------- JSF Bean,使用 CDI ------------------
import javax.enterprise.context.RequestScoped;
...
@Named
@RequestScoped
public class DemoBean {
@Inject
LocalService localService;
@PostConstruct
public void init() {
localService.reloadCache();
}
public String getName() {
return localService.getName();
}
public String getAge() {
return localService.getAge();
}
}
----------------- 服务,使用 CDI ------------------
@Named
public class LocalService {
private String name;
private String age;
public void reloadCache() {
name = null;
age = null;
name = // slow SQL on remote Service, that needs to be cached
age = // slow SQL on remote Service, that needs to be cached
}
public String getName() {
// do some work, e.g. logging
return name;
}
public String getAge() {
// do some work, e.g. logging
return age;
}
}
JSF Bean“DemoBean”使用“LocalService”类从 DB 中获取数据(通过远程 EJB,但这在这里无关紧要)。在“LocalService”类中,我想在请求期间缓存 SQL 结果有两个原因:
- SQL 查询的性能很差(很多连接,很多数据,...)
- JSF 生命周期:我不想在 6 个 JSF 生命周期中的每一个上执行 SQL 查询
如果许多 JSF Bean(对 JSF 页面的许多并发调用)同时使用注入的“LocalService”类,它的行为如何?注入的“LocalService”实例是否由其他线程共享,因此不是线程安全的?
如果是这种情况,我怎样才能使服务线程安全?
例如(在 LocalService 中)
Thread1: call reloadCache()
Thread1: call getName()
Thread1 is interrupted in the middle of getName() by Thread2
Thread2: call reloadCache()
Thread2 is interrupted in the middle of reloadCache() -> name is null
Thread1: continue execution of getName() and return name -> which is null at this moment -> very bad
这个例子是我的代码的一个非常简化的版本,但我希望它能让我的问题可以理解
谢谢,克里斯蒂安