JSF does not synchronize any access to managed beans in any scope.
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.
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.
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.