1

我有一个关于在 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

这个例子是我的代码的一个非常简化的版本,但我希望它能让我的问题可以理解

谢谢,克里斯蒂安

4

1 回答 1

3

未显式声明范围的 CDI bean 的默认范围是@Dependent. 浏览这个注解的 javadoc会告诉你,在你的特定情况下,每个实例DemoBean都保证有它自己的LocalService.

注入到由容器创建的对象中的任何 bean 实例都绑定到新创建对象的生命周期。

我将其读为为每个新创建的实例创建DemoBean并同时销毁(从长远来看,这对您来说可能很昂贵)

与您的问题无关:Denormalize。如果您发现自己进行了太多的跃点来获取数据,那么这是对过度连接问题和相关性能成本问题的简单直接的答案。但您可能已经知道这一点。

于 2013-01-30T15:55:26.263 回答