Frage

Muss das festgelegte Objekt auch einen Thread sicher sein, um sicherzustellen, dass wir wissen, wie der Zustand des in Sitzung gespeicherten Objekts bekannt ist.

Außerdem habe ich im Web gelesen, das einige vorschlagen:

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

Ist das ein gültiger Vorschlag?

War es hilfreich?

Lösung

Nein, sie sind laut IBM - nicht sicher, dass sie sicher sind - Java -Theorie und -praxis: Sind alle staatlichen Webanwendungen gebrochen?. Sie müssen synchronisieren.

Wie httpSession nicht fadensicher ist Von Java Ranch könnte auch hilfreich sein.

Andere Tipps

Servlet 2.5 Spezifikation:

Mehrere Servlets, die Anforderungs -Threads ausführen, haben möglicherweise gleichzeitig einen aktiven Zugriff auf dasselbe Sitzungsobjekt. Der Container muss sicherstellen, dass die Manipulation interner Datenstrukturen, die die Sitzungsattribute darstellen, auf Threadsafe durchgeführt wird. Der Entwickler hat die Verantwortung für den Zugriff auf Threadsafe auf die Attributobjekte selbst. Dies schützt die Attributsammlung im HTTPSession -Objekt vor dem gleichzeitigen Zugriff und beseitigt die Möglichkeit, dass eine Anwendung dazu führt, dass diese Sammlung beschädigt 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);

Das ist nicht garantiert sicher ist:

// 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 gesehen (einschließlich in J2EE -Büchern), aber es wird nicht garantiert von der Servlet -Spezifikation garantiert. Sie könnten Verwenden Sie die Sitzungs -ID, um einen Mutex zu erstellen, aber es muss einen besseren Ansatz geben.

Nein, und da Sie nicht möchten, dass derselbe Client (mit Sitzung) gleichzeitige Anfragen durchführt, sollten Sie diese Anfragen wie die serialisieren, wie die AbstractController tut im Frühjahr MVC

In gewisser Weise hängt dies von Ihrem Kundendesign ab.

Haben Sie in Ihrem Webdesign die Möglichkeit, dass ein einzelner Client mehrere ausstehende gleichzeitige Anfragen mit derselben HTTP -Sitzung durchführen kann? Dies scheint schwierig zu tun, es sei denn, Sie binden eine einzige HTTP -Sitzung an mehrere Sockets. (AKA, AJAX) Kurz davor, dass der HTTP-Zugriff eines bestimmten Clients in Bezug auf den Server Single-Threaded ist, was bedeutet, dass eine einzelne Sitzung effektiv sicher ist.

Durch die Synchronisation Ihrer Sitzungsobjekte wird die Anwendung bei zukünftigen Änderungen sicherer, die Ihre Webanwendung in der Lage sind, mehrere gleichzeitige Anfragen zu haben. 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 normalerweise nicht in Verbindung ist. Wenn Ihre Anwendung AJAX verwendet, was impliziert, dass Sie mit mehreren gleichzeitigen Anforderungen an den Flug an Ihren Webserver erwarten, ist die Synchronisierung ein Muss.

Sie sind es nicht, aber in den meisten Fällen greifen Ihre Kunden nur mit einem einzigen Thread auf sie zu.

Unterschiedliche Kunden haben unterschiedliche Themen und jeder wird eine eigene Sitzung haben.

Wie Eddie betont, ist eine Situation, in der Sie mit zwei Threads auf dieselbe Sitzung zugreifen können, zwei AJAX -Anrufe, um das gleiche Sitzungsattribut zu ändern. Andernfalls werden Sie keine Probleme haben.

Die Sitzung ist nicht sicher, und die festgelegten Methoden sind garantiert, dass die Set -Methoden sicher sind. Im Allgemeinen sollten Sie in einem Servlet -Behälter annehmen, dass Sie sich in einer Mehrfadenumgebung befinden und keine bereitgestellte Werkzeuge sicher sind.

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

Das von Ihnen veröffentlichte Code -Beispiel ist gültig, aber das Problem kann über den begrenzten Umfang Ihres Beispiels hinaus vorhanden sein. Es stellt sicher, dass es bei der Sitzung keine Bedingungen gibt, aber es gibt nichts, was einen anderen Thread verhindert, um den Satz zu überschreiben. Wenn der Code in Ihrer Anfrage davon abhängt, dass der Wert unverändert bleibt, könnten Sie immer noch in Schwierigkeiten geraten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top