2016-01-26 7 views
5

Ich benutze Mojarra 2.2.12 und in unserem Projekt haben wir ein paar @ApplicationScoped Bohnen. Zum Beispiel:Nebenläufigkeit von @ApplicationScoped JSF verwaltet Bohnen

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

Meine Frage ist, sollten wir uns Sorgen über die Sichtbarkeit des neuen zugewiesenen Wertes machen?

Ich konnte nicht in the spec finden, dass JSF-Infrastruktur den Zugriff auf @ApplicationScoped Bean Felder synchronisieren muss. Also, insbesondere für Mojarra 2.2.12, sollten wir das Feld als volatile deklarieren oder den Zugriff explizit synchronisieren?

+0

Aus meiner Sicht haben Sie einen falschen Bean-Bereich gewählt. Schwerwiegender Schmerz und Leiden werden die Folge sein, wenn der richtige Umfang einer bestimmten verwalteten Bohne nicht ausgewählt wird. – Tiny

+0

@Tiny Vielleicht ist das Caching nicht genau für Managed Beans geeignet, denke ich. Es ist eher ein Service-Zweck. –

Antwort

8

JSF tut nicht synchronisieren Sie alle Zugriffe auf verwalteten Beans in einem beliebigen Bereich.

Das ist Ihre Verantwortung. Verwenden Sie vorhandene Parallelitäts-/Synchronisations-Wrapper als Feldtypen wie AtomicInteger, ConcurrentHashMap, Collections#synchronizedList() usw. Verwenden Sie volatile nur als letzten Ausweg, wenn kein solcher Wrapper vorhanden ist.

Die Synchronisation von veränderbaren Objekten ist unbedingt in anwendungsspezifischen Beans erforderlich. Im Fall von z.B. HashMap, riskieren Sie andernfalls möglicherweise sogar eine stuck thread (100% CPU). Dies ist weniger wichtig in Session-Bean-Beans, da auf sie nur gleichzeitig zugegriffen wird, wenn der Endbenutzer mehrere HTTP-Verbindungen in derselben Sitzung öffnet, und dies nur dann geschieht, wenn zwei physisch verschiedene Browser-Instanzen erzeugt werden, die jedoch wiederum standardmäßig aktiviert werden teilen Sie die Sitzung nicht bereits. Dies würde nur im Fall von Robotern/Hackern passieren und es wird daher immer noch dringend empfohlen, dies auch in session-scoped Beans zu tun. Es ist fast nicht notwendig in Ansicht beschränkte Bohnen als Ajax-Anfragen sind by specification in die Warteschlange, aber in PrimeFaces kann es von <p:ajax async="true"> ausgeschaltet werden, und Sie müssten dies in der Ansicht beanspruchte Bean auch berücksichtigen. Es ist völlig unnötig in Request-Scoped-Beans.

Falls Sie zufällig CDI haben, können Sie optional auch die @Lock Annotation von EJB mit einer benutzerdefinierten Annotation und einem CDI Interceptor nachahmen. Dies wird detailliert im Blog von Stephan Kintelius beschrieben: Concurrency control for CDI, zufällig am Tag vor Ihrer Frage gepostet. Beachten Sie, dass die JSF-Bean-Management-Funktion gemäß JSF 2.3 zugunsten von CDI veraltet ist. Siehe auch Backing beans (@ManagedBean) or CDI Beans (@Named)? Wenn Sie können, wechseln Sie zu CDI, um Bean-Management.

+0

Interessant, aber die Spezifikation ist nicht ganz klar darüber. Ist es möglich, dass die Implementierung es synchronisiert ...? Ich meine, um Übersynchronisation zu vermeiden und einige impl-spezifische Merkmale für Performance-Sakes zu verwenden. –

+0

_Use volatile nur als letzter Ausweg, wenn keine solche Wrapper exist._ Warum denkst du so? Ich hielt das flüchtige Feld in Verbindung mit unveränderlichen Objekten für eine feste Technik für die Fadensicherheit. –

+0

Die Implementierung könnte dies tatsächlich tun, aber das wäre schlicht ineffizient, da eine Synchronisation nicht immer notwendig ist. Die Notwendigkeit hängt vom Design der Bean-Klasse ab und ist von der Implementierung an nicht sichtbar. Was "flüchtig" betrifft, sind diese Wrapper nicht unveränderbar. – BalusC