@ApplicationScoped JSF托管bean的并发性

时间:2016-01-26 08:48:33

标签: jsf jsf-2 concurrency managed-bean application-scope

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

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

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

我在the spec中找不到JSF基础结构必须同步对@ApplicationScoped bean字段的访问。因此,特别是对于Mojarra 2.2.12,我们应该将字段声明为volatile还是明确地同步对它的访问?

1 个答案:

答案 0 :(得分:8)

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

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

在应用程序范围的bean中,可变对象的同步肯定是必需的。在例如HashMap,否则您甚至可能冒stuck thread(100%CPU)的风险。会话范围bean中不太严格必要,因为只有当最终用户在同一会话中打开多个HTTP连接时才会同时访问它们,而by default仅在生成两个物理上不同的浏览器实例时才会发生,但它们将会默认情况下,已经不共享会话。所以它只会发生在机器人/黑客的情况下,因此仍然强烈建议在会话范围的bean中处理这个问题。在视图范围内的bean几乎没有必要,因为ajax请求是by specification排队的,但在PrimeFaces中它可以被<p:ajax async="true">关闭,你必须在视图范围的bean中将其考虑为好。在请求范围内的bean中完全没有必要。

如果您碰巧手头有CDI,您可以选择使用自定义注释和CDI拦截器来模仿EJB的@Lock注释。这在Stephan Kintelius的博客中详细说明:Concurrency control for CDI,巧合地在您的问题前一天发布。请记住,JSF bean管理工具是根据JSF 2.3而不赞成使用CDI。另请参阅Backing beans (@ManagedBean) or CDI Beans (@Named)?如果可以,请转到CDI进行bean管理。