Newsgroup: it.comp.java
Titolo: HttpSession Servlet e concorrenza, domanda specifica.

 httpSessione.getAttribute(MapResourceName)
Mi ero preoccupato di utilizzare delle strutture sincronizzate tipo
ConcurrentHashMap al fino di impedire a più thread su methodi diversi di
lavorare contemporaneamente sullo stesso oggetto.(da quanto capito un
thread si sarebbe messo in attesa del termine del precedente).
Questo mio amico ha affermato che questo è impossibile e non può
accadere con i servlet e che posso tranquillamente utilizzare nella
HttpSession classi non sincronizzate.
Ha ragione, questo è vero?A me sembra strano e quindi rilancio alla
vostra competente platea.
Grazie in anticipo
P.s.non ho usato un SessionBean siccome da quanto ho capito la
concorrenza viene gestita con una eccezzione  e non mettendo i thread in
attesa.
Se sono completamente in errore su ogni punto illuminatemi pure!

 Grazie in anticipo
è da un po' che non uso i servlet, quindi prendilo col beneficio del dubbio.
Riguardando i javadoc non c'è scritto che HttpSession sia thread safe ed 
inoltre i servlet gestiscono più richieste in parallelo, quindi se il 
client avesse più finestre aperte sulla stessa pagina, potrebbe fare 
richieste concorrenti, pertanto credo che il tuo approccio iniziale sia 
corretto: alla peggio perderesti qualcosina nelle prestazioni, ma 
manterresti la correttezza dell'applicazione.
qui ne discutono un po'
http://www.coderanch.com/t/361845/Servlets/java/HttpSession-not-thread-safe
--
sv.

 sv.
Grazie,
leggerò anche questo con attenzione.
Quindi sei orientato a pensarla come me, per adesso seguo la tua
indicazione e mi tengo le classi sincronizzate per sicurezza.
Spero che anche altre persone diano la loro opinione così costruisco un
campione statistico significativo di opinioni.
Saluti

 HttpSession classi non sincronizzate.
A livello teorico nulla vieta di creare un servlet container che non sia 
thread-safe.
A livello pratico tutti i servlet containers (recenti e diffusi) sono 
multithreaded e gestiscono richieste concorrenti multiple (e sessioni) 
senza necessità di intervento da parte dell'utente.
Per verificare il comportamento del container che usate voi (o per 
curiosità personale) puoi fare un rapido test con una servlet che faccia 
una sleep di qualche secondo.
Un link di spiegazione (molto sintetico):
http://www.jguru.com/faq/view.jsp?EID=150
e soprattutto i sorgenti:
http://www.docjar.com/docs/api/javax/servlet/Servlet.html
(leggi il commento alla fine del metodo service)
Considera che con il JDK 1.6 la chiamata di un metodo synchronized è 10 
volte più lenta di un metodo "normale", con le versioni precedenti i 
tempi salgono sino a 70-80 volte. Cosa facilmente verificabile con poche 
righe di codice.
Attenzione che usare oggetti sincronizzati è diverso da rendere 
sincronizzati i metodi chiamanti e/o sincronizzare gli oggetti che 
contengono questi metodi. La cosa non mi sembrava chiarissima dalla tua 
domanda originaria... :)
Per rendere l'idea un vecchio, vecchissimo tutorial IBM su come evitare 
l'"oversincronizzazione" delle servlet:
http://www.ibm.com/developerworks/websphere/library/bestpractices/avoiding_or_minimizing_synchronization_in_servlets.html
e un tutorial più recente (relativamente...) e prolisso (ma 
sostanzialmente molto simile):
http://www.javaworld.com/javaworld/jw-07-2004/jw-0712-threadsafe.html
Ciao,
Pablo

 domanda originaria... :)
Ti ringrazio per le spiegazioni,
 da quanto avevo capito un metodo sincronizzato può essere eseguito da
un thread alla volta (mettendo in attesa gli altri thread) mentre una
classe sincronizzata garantisce la consistenza dei dati anche se più
thread ne richiedono l'uso.(cosa che il più delle volte mi sarebbe
bastato, ma che suppongo venga garantito facendo lavorare un thread alla
volta..ma sono ipotesi).
Leggendo la documentazione ho notato che alcune classi sincronizzate
garantiscono la concorrenza generando una eccezione mentre, ad esempio,
ConcurrentHashMap fa il lavoro che preferisco, ovvero garantisce la
consistenza dei dati in modo trasparente.
Le mie sono giuste interpretazioni?
Leggerò i link che hai postato.
Ancora grazie
saluti

 volta..ma sono ipotesi).
Ho approfondito dai links e sebbene l'effetto finale dovrebbe essere
quello da me preventivato, soprattutto per le Concurrent Collections, i
perchè sono diversi da quanto ipotizzato.
Comunque se volete puntualizzare qualcosa.. ditemi pure.

 Comunque se volete puntualizzare qualcosa.. ditemi pure.
mah io sinceramente ho delle perplessità su come tu vedi il problema 
della concorrenza sulla sessione.
mi spiego: tu puoi avere effettivamente due thread che accedono 
contemporaneamente alla sessione, ma perché ciò accada occorre 
necessariamente che un utente abbia due o più finestre del browser 
aperte sulla stessa applicazione. ma se affronti questo aspetto ti si 
apre un mondo di problematiche importanti e con le sincronizzazione dei 
thread non ne risolvi manco mezza. faccio un esempio pratico: se tu hai 
una pagina jsf che usa dei session bean nel momento in cui l'utente apre 
due istanze della pagina hai chiaramente un problema di coerenza fra lo 
stato della pagina e quello del session bean, senza bisogno che le 
richieste siano simultanee.

 richieste siano simultanee.
Comprendo le tue perplessità, ma sarò più preciso:
il mio applicativo GWT non necessita di ricavare informazioni sullo
stato della pagina dalla SessionBean o HttpSession.
Nella sessione vengono solo memorizzati delle strutture dati in una
Map.L'indice della mappa identifica i dati della singola pagina aperta,
quindi ogni pagina-GWT accede solo ai suoi dati.
 Naturalmente la Map è  una classe potenzialmente "condivisa" tra le
pagine GWT.
Il caso di più finestre GWT contemporanee è  alquanto raro ma non è il
solo da cui cerco di proteggermi.
Il server potrebbe avere la necessità di effettuare nel mentre dei test
sulla coerenza dei dati per correggere o eliminare dati dalla struttura
o anche soltanto per effettuare dei calcoli (azioni fatte scattare da
listener o simili), quindi il problema della concorrenza non nasce per
me dalla sola interazione con il client(browser remoti).
Il fatto che io abbia deciso di non usare per ora i SessionBean nasce
dal fatto che avevo già imparato ad usare l'HttpSession, in più avevo
letto(anche se avrebbe meritato approfondimento) che i SessionBean
risolvono i problemi d concorrenza impedendo chiamate RMI contemporanee
soltanto generando una Eccezione. E questo avrebbe aumentato al
complessità del mio applicativo.
Soprattutto sulle mie ultime affermazioni attendo i vostri pareri.
Grazie && Saluti

 richieste siano simultanee.
Tanto per spezzare una lancia a favore di Seam, esso risolve 
brillantemente entrambe le problematiche.
Per quanto riguarda la prima serializza gli accessi ai bean di sessione.
Per la seconda offre lo scope di conversazione.
Senza Seam purtroppo si deve lavorare in request, e lasciare al client 
(attraverso campi nascosti e parametri) il compito di mantenere lo stato.

 thread-safe.
E' sufficiente che una servlet implementi SingleThreadModel. Ma 
ovviamente non lo fa nessuno, almeno si spera.

 (attraverso campi nascosti e parametri) il compito di mantenere lo stato.
E' un poco quello che faccio con GWT, la cosa in se è abbastanza
semplice, di fatto il mio problema non era tanto come fare a garantire
la consistenza, ma capire effettivamente come funzionavano le varie
strutture (tipo concurrentHashTable) e i metodi sincronizzati nel
dettaglio e valutare alternative.
Comunque interessante questo Seam non l'avevo mai sentito nominare.
Grazie e saluti
Fabiano

 ovviamente non lo fa nessuno, almeno si spera.
Si spera, anche perché è una best practice: implementare 
SingleThreadModel in una servlet significherebbe creare un'istanza della 
servlet per ogni sessione utente.
Ciao,
Pablo

Pablo ha scritto:

Effettivamente sarebbe una cosa abbastanza insensata soprattutto per un
applicativo che deve scalare bene.
Se lo devono usare 4 gatti (uso interno) o per fare esperimenti, forse
può anche andare.