Concurrency of @ApplicationScoped JSF managed beans
Asked Answered
B

1

6

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?

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?

Biomedicine answered 26/1, 2016 at 8:48 Comment(2)
To my point of view, you have chosen a wrong bean scope. Severe pain and suffering will be the consequences of failing to choose a right scope of a particular managed bean.Veneering
@Veneering Maybe, the caching is not strictly speaking suitable for managed beans, I think. It's rather a service purpose.Biomedicine
B
10

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.

Brooking answered 26/1, 2016 at 8:55 Comment(7)
Interesting, but the spec does not quite clear about it. Is it possible for implementation to synchronize it...? I mean, to avoid oversyncrhonization and use some impl-specific features for perfomance sakes.Biomedicine
Use volatile only as last resort if no such wrapper exist. Why do you think so? I thought volatile field combined with immutable objects is a stnadrd techique for thread-safety.Biomedicine
The implementation could indeed choose to do so, but that would be plain inefficient as synchronization is not always necessary. The necessity depends on bean class design and this is invisible from the implementation on. As to volatile, those wrappers aren't immutable.Brooking
I'd like to ask you one more question about SessionScoped beans. I thought, synchronization is a desirable thing for them. Container may access such beans when persisting a session as well as a web-application in order to respond a request. That way, concurrent access may occur even without accessing from the same browser/robots/hackers. Isn't thast true?Biomedicine
It may be necessary, but just less stricty as those conditions depend on web application design and audience. As to session persistence, during that moment there's in first place no means of a request working on it, the container already worries about that part. As to requests on same session, the container synchronizes requests on the same HTTP connection (see also "by default" link).Brooking
@BalusC: If it is running in a 64-bit system, a variable having value (56783423L) will be written using a single operation, but on a 32-bit one, the variable will be written using two separate operations. To recapitulate, I should not bother about synchronisation/atomicity if system is 64-bit, or synchronization of mutable objects is still definitely necessary for a 64-bit system. Kindly suggest.Ulaulah
@Shirgill: JVM abstracts away this. You should in Java code not worry about platform architecture (and that would otherwise defeat Java's own primary ideology of being platform independent).Brooking

© 2022 - 2024 — McMap. All rights reserved.