6

我正在使用 Mojarra 2.2.12,在我们的项目中,我们有一些@ApplicationScopedbean。例如:

@ManagedBean
@ApplicationScoped
public class AppScopedBean{

    private int commonValueForClients;

    //GET, SET

    public void evalNew(){
        int newCommonVal;
        //Evaluation of the new value, doesn't depend on the commonValueForClients
        commonValueForClients = newCommonVal;
    }
}

我的问题是我们应该担心新分配值的可见性吗?

我在规范中找不到JSF 基础设施必须同步对@ApplicationScopedbean 字段的访问。那么,特别是对于 Mojarra 2.2.12,我们应该将该字段声明为volatile还是显式同步对它的访问?

4

1 回答 1

10

JSF 不会同步对任何范围内的托管 bean 的任何访问。

那是你的责任。使用现有的并发/同步包装器作为字段类型,例如AtomicInteger, ConcurrentHashMap,Collections#synchronizedList()等。volatile如果不存在这样的包装器,请仅作为最后的手段使用。

在应用程序范围的 bean 中,可变对象的同步绝对是必要的。在这种情况下HashMap,您甚至可能面临线程卡住(100% CPU)的风险。在会话范围的 bean 中没有那么严格的必要性,因为它们只会在最终用户在同一会话上打开多个 HTTP 连接时同时访问,并且默认情况下只会在产生两个物理上不同的浏览器实例时发生,但它们会依次通过默认已经不共享会话。所以它只会在机器人/黑客的情况下发生,因此仍然强烈建议在会话范围的 bean 中也处理这个问题。在视图范围的 bean 中几乎没有必要,因为 ajax 请求是规范的排队,但在 PrimeFaces 中,它可以通过 关闭<p:ajax async="true">,您还必须在视图范围 bean 中考虑到这一点。在请求范围的 bean 中完全没有必要。

如果您碰巧手头有 CDI,您还可以选择 @Lock使用自定义注释和 CDI 拦截器来模仿 EJB 的注释。这在 Stephan Kintelius 的博客中有详细说明:CDI 的并发控制,恰好在您提出问题的前一天发布。请记住,JSF bean 管理工具根据 JSF 2.3 已弃用,而支持 CDI。另请参见支持 bean (@ManagedBean) 或 CDI Bean (@Named)?如果可以,请转到 CDI 作为 bean 管理。

于 2016-01-26T08:55:01.633 回答