@ApplicationScoped JSF 托管 bean 的并发性 [英] Concurrency of @ApplicationScoped JSF managed beans

查看:27
本文介绍了@ApplicationScoped JSF 托管 bean 的并发性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 Mojarra 2.2.12,在我们的项目中,我们有一些 @ApplicationScoped bean.例如:

I'm using Mojarra 2.2.12 and in our project we've got a few @ApplicationScoped beans. For instance:

@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;
    }
}

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

My question is should we worry about visibility of the new assigned value?

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

I couldn't find in the spec that JSF infrastructure must synchronize access to @ApplicationScoped bean fields. So, particularly for Mojarra 2.2.12, should we declare the field as volatile or synchronize access to it explicitly?

推荐答案

JSF同步对任何范围内的托管 bean 的任何访问.

JSF does not synchronize any access to managed beans in any scope.

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

That's your responsibility. Use existing concurrency/synchronization wrappers as field types such as AtomicInteger, ConcurrentHashMap, Collections#synchronizedList(), etc. Use volatile only as last resort if no such wrapper exist.

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

Synchronization of mutable objects is definitely necessary in application scoped beans. In case of e.g. HashMap, you may otherwise even risk a stuck thread (100% CPU). It is less strictly necessary in session scoped beans as they will only be accessed concurrently when the enduser opens multiple HTTP connections on the same session, and this will by default only happen when two physically different browser instances are spawned, but they will in turn by default already not share the session. So it would only happen in case of robots/hackers and it's therefore still strongly recommended to take care of this in session scoped beans as well. It is nearly unnecessary in view scoped beans as ajax requests are by specification queued, but in PrimeFaces it can be turned off by <p:ajax async="true">, and you'd have to take that into account in the view scoped bean as well. It is totally unnecessary in request scoped beans.

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

In case you happen to have CDI at hands, you could optionally also mimic EJB's @Lock annotation with a custom annotation and a CDI interceptor. This is detailed in Stephan Kintelius' blog: Concurrency control for CDI, coincidentally posted the day before your question. Keep in mind that JSF bean management facility is as per JSF 2.3 deprecated in favor of CDI. See also Backing beans (@ManagedBean) or CDI Beans (@Named)? If you can, move to CDI as to bean management.

这篇关于@ApplicationScoped JSF 托管 bean 的并发性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆