Ist HttpSession threadsicher, sind Attribute thread safe-Operationen gesetzt / erhalten?

Außerdem muss das Objekt, das gesetzt wird, Thread-sicher sein, um zu garantieren, dass wir wissen, wie der Zustand des in der Sitzung gespeicherten Objekts bekannt ist.

Außerdem habe ich im Internet gelesen, dass einige vorschlagen:

synchronized(session) { session.setAttribute("abc", "abc"); } 

Ist das ein gültiger Vorschlag?

   

Nein, sie sind nicht threadsicher, laut IBM – Java Theorie und Praxis: Sind alle statusreichen Webanwendungen kaputt? . Sie müssen synchronisieren.

Wie HttpSession nicht Thread-sicher von Java Ranch ist, könnte auch hilfreich sein.

Servlet 2.5 Spezifikation:

Mehrere Servlets, die Anfragethreads ausführen, können gleichzeitig aktiven Zugriff auf dasselbe Sitzungsobjekt haben. Der Container muss sicherstellen, dass die Manipulation der internen Datenstrukturen, die die Sitzungsattribute darstellen, in einer Thread-sicheren Weise durchgeführt wird. Der Entwickler hat die Verantwortung für den Thread-sicheren Zugriff auf die Attributobjekte selbst. Dadurch wird die Attributsammlung innerhalb des HttpSession-Objekts vor gleichzeitigem Zugriff geschützt, wodurch die Möglichkeit für eine Anwendung, dass diese Sammlung beschädigt wird, eliminiert wird.

Das ist sicher:

 // guaranteed by the spec to be safe request.getSession().setAttribute("foo", 1); 

Das ist nicht sicher:

 HttpSession session = request.getSession(); Integer n = (Integer) session.getAttribute("foo"); // not thread safe // another thread might be have got stale value between get and set session.setAttribute("foo", (n == null) ? 1 : n + 1); 

Dies ist nicht garantiert, um sicher zu sein:

 // no guarantee that same instance will be returned, // nor that session will lock on "this" HttpSession session = request.getSession(); synchronized (session) { Integer n = (Integer) session.getAttribute("foo"); session.setAttribute("foo", (n == null) ? 1 : n + 1); } 

Ich habe diesen letzten Ansatz befürwortet (einschließlich in J2EE-Büchern), aber es ist nicht garantiert, dass er nach der Servlet-Spezifikation funktioniert. Sie könnten die Sitzungs-ID verwenden, um einen Mutex zu erstellen , aber es muss eine bessere Vorgehensweise geben.

Nein. Und da Sie nicht möchten, dass derselbe Client (mit der Sitzung) gleichzeitige Anfragen ausführt, sollten Sie diese Anfragen serialisieren, wie es der AbstractController in Spring MVC tut

In gewisser Weise hängt dies von Ihrem Client-Design ab.

Haben Sie in Ihrem Webdesign die Möglichkeit, dass ein einzelner Client mehrere ausstehende gleichzeitige Anforderungen mit derselben HTTP-Sitzung hat? Dies scheint schwierig zu sein, wenn Sie nicht eine einzelne HTTP-Sitzung an mehrere Sockets binden. (aka, AJAX) Kurz gesagt, wird der HTTP-Zugriff eines bestimmten Clients für den Server single-threaded sein, was bedeutet, dass eine einzelne Sitzung effektiv Thread-sicher ist.

Durch die Synchronisierung Ihrer Sitzungsobjekte wird die Anwendung sicherer vor zukünftigen Änderungen, die Ihre Webanwendung in die Lage versetzen, mehrere gleichzeitige Anforderungen zu erfüllen. Dies ist also keine schlechte Idee. In modernen Java-Implementierungen hat die Synchronisation nicht die großen Kosten, die zuvor damit verbunden waren, insbesondere wenn die Synchronisation in der Regel nicht berücksichtigt wird. Wenn Ihre Anwendung AJAX verwendet, was bedeutet, dass Sie mehrere simultane Anfragen während des Flugs an Ihren Webserver erwarten, ist die Synchronisierung ein Muss.

Sie sind es nicht, aber die meisten Kunden greifen nur mit einem einzigen Thread auf sie zu.

Verschiedene Clients haben unterschiedliche Threads und jeder hat seine eigene Session.

Wie Eddie hervorhebt, ist eine Situation, in der zwei Threads auf dieselbe Sitzung zugreifen können, zwei Ajax-Aufrufe, die versuchen, dasselbe Sitzungsattribut zu ändern. Sonst wirst du keine Probleme haben.

Die Sitzung ist nicht threadsicher und weder die get-Methode noch die set-Methode sind garantiert threadsicher. Im Allgemeinen sollten Sie in einem Servlet-Container davon ausgehen, in einer Umgebung mit mehreren Threads zu sein, und keine bereitgestellten Tools sind sicher.

Dies gilt auch für die Objekte, die Sie in der Sitzung speichern. Die Sitzung selbst wird das gespeicherte Objekt nicht manipulieren, aber Sie können das Objekt in einem anderen Thread abrufen und versuchen, es zu manipulieren. Es liegt an Ihnen, Ihren eigenen Code zu prüfen, um zu sehen, ob Rennbedingungen möglich sind.

Das Codebeispiel, das Sie gepostet haben, ist gültig, aber das Problem kann außerhalb des begrenzten Bereichs Ihres Beispiels bestehen. Es stellt sicher, dass beim Festlegen der Sitzung keine Bedingungen vorhanden sind, aber nichts verhindert, dass ein anderer Thread die Gruppe überschreibt. Wenn der Code in Ihrer Anfrage davon abhängt, dass der Wert unverändert bleibt, könnten Sie immer noch Probleme haben.