Il thread di HttpSession è sicuro, le operazioni di thread di Attribute sono impostate / ottenute?

StackOverflow https://stackoverflow.com/questions/616601

Domanda

Inoltre, l'oggetto impostato deve essere thread-safe per garantire che conosciamo lo stato dell'oggetto memorizzato nella sessione.

Inoltre, stavo leggendo sul web che alcuni suggeriscono di usare:

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

È un suggerimento valido?

È stato utile?

Soluzione

No, non sono thread-safe, secondo IBM - Teoria e pratica Java : Tutte le applicazioni Web stateful sono rotte? . Devi sincronizzare.

In che modo HttpSession non è thread-safe dal Java Ranch potrebbe anche essere utile.

Altri suggerimenti

Specifica servlet 2.5:

  

Più servlet che eseguono la richiesta   i thread possono avere accesso attivo a   stesso oggetto sessione allo stesso tempo.   Il contenitore deve garantire che   manipolazione di dati interni   strutture che rappresentano la sessione   gli attributi vengono eseguiti in a   modo sicuro per i thread. Lo sviluppatore ha   la responsabilità di threadsafe   accesso agli oggetti attributo   loro stessi. Questo proteggerà il   raccolta di attributi all'interno di   Oggetto HttpSession da simultaneo   accesso, eliminando l'opportunità   affinché un'applicazione lo causi   collezione da corrompere.

Questo è sicuro:

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

Questo è non sicuro:

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);

Questo è non garantito per essere sicuro:

// 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);
}

Ho visto questo ultimo approccio raccomandato (incluso nei libri J2EE), ma non è garantito che funzioni secondo le specifiche Servlet. Puoi utilizzare l'ID sessione per creare un mutex , ma deve esserci un approccio migliore.

No. E poiché non vuoi che lo stesso client (con sessione) esegua richieste simultanee, dovresti serializzare queste richieste come AbstractController funziona in Spring MVC

In qualche modo, questo dipende dal design del tuo cliente.

Hai la possibilità, nel tuo web design, che un singolo client abbia più richieste simultanee in sospeso utilizzando la stessa sessione HTTP? Questo sembra difficile da fare a meno che non si colleghi una singola sessione HTTP a più socket. (aka, AJAX) A parte questo, l'accesso HTTP di un determinato client sarà a thread singolo per quanto riguarda il server, il che significa che una singola sessione è effettivamente thread-safe.

La sincronizzazione degli oggetti della sessione renderà l'applicazione più sicura rispetto alle modifiche future che renderanno l'applicazione Web in grado di avere più richieste simultanee, quindi non è una cattiva idea. Nelle moderne implementazioni Java, la sincronizzazione non ha il grande costo che era precedentemente associato ad essa, specialmente quando la sincronizzazione è di solito non consigliata. Se l'applicazione utilizza AJAX, il che implica che ti aspetti più richieste simultanee in volo al tuo server web, la sincronizzazione è un must.

Non lo sono, ma la maggior parte delle volte, i tuoi clienti accederanno a loro solo con un singolo thread.

Client diversi avranno thread diversi e ognuno avrà la propria sessione.

Come sottolinea Eddie, una situazione in cui è possibile affrontare due thread accedendo alla stessa sessione è che due chiamate ajax stanno tentando di modificare lo stesso attributo di sessione. Altrimenti non avrai problemi.

La sessione non è thread-safe e né i metodi get not set sono garantiti come thread safe. In generale in un contenitore servlet dovresti presumere di trovarti in un ambiente multi-thread e nessuna attrezzatura fornita è sicura.

Questo vale anche per gli oggetti che memorizzi nella sessione. La sessione stessa non manipolerà l'oggetto memorizzato ma è possibile recuperarlo in un thread diverso e tentare di manipolarlo. Sta a te esaminare il tuo codice per vedere se le condizioni di gara sono possibili.

L'esempio di codice che hai pubblicato è valido, ma il problema potrebbe esistere oltre l'ambito limitato del tuo esempio. Assicura che non ci siano condizioni durante l'impostazione della sessione, ma nulla impedisce a un altro thread di sovrascrivere il set. Se il codice nella tua richiesta dipende dal valore che rimane invariato, potresti essere ancora nei guai.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top