Newsgroup: it.comp.java
Titolo: arraylist e thread safe

gli arraylist non sono thread safe da documentazione
ecco, lavorando su web (jsp, struts e jsf) a me non è mai capitato di
avere problemi, e, anche volendo creare una situazione per provare la
cosa,  non riesco
sapreste farmi un esempio? anche su una semplicissima pagina .jsp dove
scrivo del codice
grazie
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 cosa,  non riesco
Ti giro un link che, per quanto vecchietto, credo sia esplicativo:
http://www.jguru.com/faq/view.jsp?EID=150

Pablo ha scritto:


è sulle servlet, quelle ho idea di come funzionano
se mi spieghi la connessione ci arrivo (forse :-))


 è sulle servlet, quelle ho idea di come funzionano
Allora hai tutto chiaro: le jsp vengono "tradotte" in servlet, compilate 
e poi eseguite ;-)
O forse non ho capito io i tuoi dubbi.

 scrivo del codice
L'esempio con il codice non è necessario.
Pensa ad un bean di scope "application" (visto che mastichi JSF), con un 
ArrayList per gestire i messaggi di una chat.
Hai bisogno di una lista thread safe, ci sei?

Pablo ha scritto:



rispondo a te, spero di spiegare anche all'altro utente
io ho provato a usare l'arraylist in una jsp (codice in pagina in maniera
brutale per l'esempio) chiamata in contemporanea da 2 client e mi pare che
vengano creati 2 thread diversi 
ecco


 ecco
Stai trollando per caso?

 vengano creati 2 thread diversi
Il numero di thread non c'entra: l'istanza della jsp (ove non 
sincronizzata) č condivisa, per cui modificando una variabile di classe 
su una jsp trovi la modifica anche sull'altra.
Molto terra-terra...

 Molto terra-terra...
ho creato un arrayList a cui aggiungevo elementi da una parte e dall'altra
(intendo dai 2 client), e pareva rimanessero separati


 Stai trollando per caso?
ma poi, al posto di sprecare tempo per una uscita simile, dimmi cosa fare
in una jsp (saranno 3 righe di codice) in modo da verificare il fatto che
arrayList non sia thread-safe, l'esempio che hai fatto della chat ci può
stare ma non posso implementare una chat tanto per provare un esempio
(magari per te è facilissimo, per me no)


 Molto terra-terra...
ma poi scusa, questo comportamento avviene anche su una variabile di tipo
String (ad esempio) e non solo sugli ArrayList, proprio perchč la servlet
generata dalla jsp non č threadsafe


 generata dalla jsp non è threadsafe
Esatto, avviene su tutto quello che non è synchronized.
"nota operativa": attenzione che la punteggiatura un po' latitante, la 
forma gergale/colloquiale e la mancanza di smiley o simili non fa ben 
capire se si tratti di domande, affermazioni, affermazioni ironiche... :-)
Risulta difficile risponderti ed effettivamente può nascere il sospetto 
che possano essere trollate ;-)

 Esatto, avviene su tutto quello che non è synchronized.
Ok ma quindi non mi pare un esempio per dimostrare il fatto che non siano
threadsafe gli ArrayList visto che, in questo caso, non sono threadsafe
manco le Stringhe o altri oggetti.
Esempio di codice:
ArrayList aList = new ArrayList ();
for(int i=1, i < 10...){
aList.add("elemento "+i);
}
quando scrivo questo codice in una pagina jsp e chiamo la pagina da 2
client diversi contemporaneamente, alla fine, mi trovo con un oggetto che
contiene 10 elementi; essendo oggetti non-threadsafe mi dovrei ritrovare
20 elementi, no? insomma se aList è una risorsa condivisa, entrambe le
pagine dovrebbero andare a incrementarla, o mi sbaglio?
grazie


 pagine dovrebbero andare a incrementarla, o mi sbaglio?
Sì, sbagli perché è condiviso anche l'"istanziamento" della lista.
Prova a mettere un codice che impieghi qualche secondo e setti una 
variabile poi mandata in output sulla response.

 variabile poi mandata in output sulla response.
Quel 10 è un n molto grosso ovviamente, proprio per creare una cosa
simultanea da 2 browser; il codice è nel body della jsp e non in un metodo.
Grazie


 (magari per te è facilissimo, per me no)
Il perchè di un'uscita simile esiste, fidati. Ma mi pare di aver capito 
che non è il tuo caso, non stai trollando.
Il problema è che non hai la ben che minima idea di cosa sia la thread 
safety: una struttura dati thread safe non è una struttura dati che 
esiste separatamente in ciascun thread.
Comunque è perfettamente inutile spiegartelo: apri google, fai la tua 
ricerca e studia la materia. Vedrai che non perdi tempo, anzi.

 esiste separatamente in ciascun thread.
 
Non penso di avere detto questo, ho solo detto che se č threadsafe i 2
client non accedono allo stesso arraylist ed č cosě che a me accade. La
cosa mi stupisce vista la documentazione Java che dice invece che non č
threadsafe.
Poi ok posso riguardare il tutto per capire meglio.


 threadsafe.
No, se una classe č thread-safe significa che 2 o piů thread posso 
utilizzarne un'istanza (la stessa istanza) contemporaneamente, senza che 
questo crei problemi allo stato interno dell'istanza.
Se invece i tuoi thread usano istanze diverse, non hai nessun problema 
di thread-safety.
In ogni caso l'unico modo per testare se una classe ha o meno problemi 
di thread-safety č quello di metterla sotto stress, cioč farla usare 
contemporaneamente da MOLTI thread, e verificare che inizia ad avere 
comportamenti inconsistenti (e non č detto che accada sempre, si puň 
essere fortunati :) ).
Sicuramente non č una cosa verificabile A MANO, cliccando sul refresh di 
un browser.
Guarda questo esempio che verifica la non-thread-safety della classe 
SimpleDateFormat:
http://i-proving.ca/space/Kevin+Allen/blog/2006-11-28_1
In ogni caso, se la documentazione della classe dice che non č 
thread-safe, perchč non ti fidi? Se proprio non ti fidi, č molto 
semplice accorgersene dando una rapida occhiata ai sorgenti:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java
I metodi pubblici non sono sincronizzati e accedono direttamente alle 
strutture interne della classe...quindi quella classe non puň essere 
thread-safe.
-- 
Lucio Benfante       
http://www.lambico.org
JUG Padova           
http://www.parancoe.org
www.jugpadova.it
 
http://www.jugevents.org

 thread-safe, perchè non ti fidi?  
Eh, bella domanda.
Grazie a tutti


 casi possibili.
No...stai letteralmente andando a farfalle. Dovresti proprio leggerti un 
buon libro su thread e concorrenza.
Ad esempio:
http://jcip.net/
Ciao
   Lucio


 buon libro su thread e concorrenza.
 
Scusa ma qua ti ho quotato e dato ragione, non ci siamo capiti ma non
stavo andando per farfalle. Rispiego: l'esempio che avevo fatto dimostrava
poco perchè, come dici tu, "Sicuramente non è una cosa verificabile A
MANO, cliccando sul refresh di un browser." 
-- 


 vengano creati 2 thread diversi
questo ti pare bene, le jsp vengono eseguite su thread diversi.
ma se l'arraylist è una reference locale della jsp il problema della
concorrenza non si pone, hai un istanza diversa di arraylist per ogni
thread.
se vuoi creare un esempio di concorrenza è sufficiente che l'arraylist
sia una reference static o, più pulito, un singleton. però riprodurre
le problematiche di concorrenza direttamente sulle jsp è una tecnica
abbastanza improbabile, userei piuttosto una test suite scritta ad
hoc.

 sia una reference static  
Ok, fosse static l'arrayList, le 2 pagine chiamerebbero la stessa istanza
e quindi ci potrebbero essere dei problemi; ora ti chiedo, se invece di
usare un ArrayList, usiamo un Vector (che dovrebbe essere threadsafe)
static, i suoi metodi gestirebbero la concorrenza, giusto?
Grazie


 MANO, cliccando sul refresh di un browser."
Sì, ma soprattutto non è "uno dei casi possibili". Quello che è 
difficile è individuare sono i casi reali. Non stiamo parlando di casi 
evidenti (come quello della servlet di cui si parlava sopra). Il tuo 
esempio al massimo cerca di verificare la thread-safety della servlet, 
non dell'ArrayList.
Ad esempio, in uno scenario del genere, ho dei thread che eseguono la 
seguente e unica operazione sulla medesima istanza di ArrayList 
identificata dal reference miaLista:
public void run() {
   miaLista.add("Pippo");
}
Se non ti aspetti un problema di concorrenza...beh, meglio che te lo 
aspetti. :)


 aspetti. :)
 
Ok, è la situazione che credevo di potere creare io quando ho parlato
delle jsp.
Nello specifico quale problema si verificherebbe?
E invece usando un oggetto threadsafe (Vector ad esempio) cosa accadrebbe
di diverso?
+o- me lo immagino ma non vorrei dire qualche boiata :-)
Grazie ancora


 static, i suoi metodi gestirebbero la concorrenza, giusto?
i metodi sono thread-safe, punto. non sbilanciamoci in considerazioni
che sono formalmente scorrette, "gestire la concorrenza" non è un
argomento che si liquida in questo modo. in questo pezzo di codice, ad
esempio:
if( list.size() > i )
  o = list.get(i);
non c'è nessuna thread safety della collection che può pararti le
terga.

 esempio:
 
ok grazie


 esempio:
 
ok grazie


 Grazie ancora
Lucio per me č abbastanza cosě, non andiamo oltre, i concetti li ho
chiariti.


 di diverso?
Non accadrebbe mai di avere problemi di concorrenza su chiamate a metodi 
di tale oggetto.
Interessante vedere le implementazioni di add in ArrayList e Vector 
dell'OpenJDK:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#ArrayList.add%28java.lang.Object%29
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Vector.java#Vector.add%28java.lang.Object%29
Nota che in Vector c'erano (ci sono? non ho verificato il codice 
dell'ultimo OpenJDK) dei bug, ed erano quasi tutti relativi alla 
concorrenza, pur essendo una classe decisamente vecchia. Il che dimostra 
quanto sia difficile scrivere qualcosa ed essere sicuri che sia 
realmente thread-safe.


 realmente thread-safe.
Diciamo che, l'errore che facevo nella mia valutazione iniziale, era
concentrarmi poco sul synchronized che è quello che evita accessi
concorrenti.
Tra l'altro è una cosa che avevo già visto ma, usandola poco in esempi
concreti, mi ero scordato.
Sì, ho letto dei bug di Vector, non so se siano stati eliminati.
Grazie
