我正在使用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
还是明确地同步对它的访问?
答案 0 :(得分:8)
JSF确实不同步对任何范围内托管bean的任何访问。
这是你的责任。使用现有的并发/同步包装器作为字段类型,例如AtomicInteger
,ConcurrentHashMap
,Collections#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管理。