Newsgroup: it.comp.java
Titolo: R: Thread & volatile - Qualcuno ha una risposta ?

 ha scritto nel messaggio
news:3J2t5.4845$_U1....@news.infostrada.it...


 wrote in message
8p2siq$stt$1...@lacerta.tiscalinet.it...


Ho dato un occhio sulla Java Developer Connection cercando
volatile nella bug-parade!
E' pieno di segnalazioni sulla mancata iplementazione o iplementazione
bacata della clausola 'volatile'
Mi sa proprio che ancora per qualche JDK sia maeglio utilizzare
synchronized!

 wrote in message
8p50v8$sij$1...@pegasus.tiscalinet.it...


 ha scritto nel messaggio
news:Tbot5.12451$_U1.2...@news.infostrada.it...


 wrote in message
8p579j$n8a$1...@lacerta.tiscalinet.it...


Mi spiace contraddirvi, ma nelle mie prove sperimentali (Win98, sia
jdk1.3 che jbuilder3) non ho rilevato neanche un eroore pur avendo
lasciato loopare per qualche centinaio di milioni di iterazioni. Per
cui posso ritenere affidabile la clausola volatile, almeno nel mio
sistema e in certe situazioni tra cui l'esempio proposto e piccole
varianti da me effettuate per il test.
Per caso vi dà tale errore anche se invertite l'ordine degli operandi
? ( if (j2 > j1) ). E' solo per eliminare un'ipotesi assurda.
Ciao, Max.

 wrote in message
news:8p0hqv$add$1...@pegasus.tiscalinet.it...


>  }
- inc  => incrementa le due variabili volatile i1 e i2, ma le
incrementa in un ordine molto particolare: prima i1, poi i2; per cui,
essendo questo l'unico metodo in grado di modificare il valore di tali
variabili, e partendo tali variabili entrambe da uno stato iniziale di
zero, SICURAMENTE il valore di i2 non potrà mai, in nessun istante,
essere maggiore di i1, ma semmai il contrario se cerco di leggere i1 e
i2 a metà dello svolgimento di tale metodo (i1 appena incrementata na
i2 non ancora);
- check => tale metodo stampa un messaggio solo nel caso che i2>i1,
cosa inaccettabile per il motivo prima illustrato. Spero che questa
spiegazione ti abbia fatto capire la natura del problema che non
dovrebbe esserci se la clausola volatile funzionasse sempre a dovere
(cosa che però dipende dalla VM utilizzata, e questo è quindi un
problema perché java diventa non più portabile nella sua clausola
"volatile", dipendendo nel funzionamento dalla VM utilizzata).
Ciao, Max.

Per prima cosa vorrei ringraziare Max per il suo messaggio e scusarmi per il
ritardo con cui replico...
Non mi trovo pero' in accordo con il ritenere impossibile (e quindi segno di
errori nell'implementazione della JVM) il fatto che i1 possa essere minore
di i2.
La valutazione dell'espressione (e di ogni altra operazione come ad esempio
i++) i1<i2 non viene eseguita in un unico turno di CPU.
Ad es. si potrebbero verificare i seguenti passi:
1) il valore di i1 (attualmente a 0) viene caricato nel registro come primo
operatore della diseguaglianza (ATTENZIONE: questa non e' la stessa cosa di
avere copie locali)
2) il thread perde il turno di CPU
3) lavorano altri thread fra cui il thread che incrementa i1 e i2
(portandoli entrambi a 1)
4) il nostro thread riottiene l'uso della CPU, carica il valore di i2 come
secondo operatore della diseguaglianza ----> si ha che i1 e' minore di i2.
Questa e' la mia interpretazione del 'fenomeno' e del significato della
clausola volatile.
Sarei felice di avere un vostro riscontro.
Ciao


? ( if (j2 > j1) ). E' solo per eliminare un'ipotesi assurda.
Perché anche a me era passata per la testa tale idea, e l'unico modo
per verificarlo era compiere la stessa operazione invertendo gli
operandi, cosa possibile solo per chi tale problema lo aveva (io non
ce l'ho, neanche invertendo gli operandi).
Dapprima mi sembrava comunque un ipotesi remota perché immaginavo che
la VM, per tenere fede agli obblighi imposti dalla keyword volatile,
difficilmente riutilizzasse lo stack precedente se le variabili
coivolte erano volatile durante un cambio di guardia nel thread attivo
(supponendo una semplice schedulazione di Round Robin per la VM, si
parla di un bel po' di msec passati dall'ultima operazione effettuata
dal thread in precedenza, ed è  facile che nel frattempo tale
variabile sia mutata); quindi immaginavo che in qualche modo, almeno a
livello dello stesso metodo, la VM faccesse un controllo sulle
variabili allocate nello stack corrente dal metodo e se ne individuava
una volatile la sostituisse subito con quella corretta (più difficile
sarebbe scorrere indietro lo stack a livello di altri metodi chiamanti
individuando le variabili volatili, a meno di etichettarle
appesantendo l'efficienza della VM). 
Chiaramente stavo solo pensando con la tastiera a portata di mano,
perché non avevo/ho la più pallida idea di come questo argomento sia
realmente affrontato a livello di implementazione di VM (sono curioso
ma il tempo di esaminare il codice così a fondo non ce l'ho :-( ).
Ciò non toglie che se tu hai ragione allora l'inversione che io avevo
richiesto di fare (porre j2>j1 anzichè j1<j2) dovrebbe risolvere
definitivamente il problema.
Ciao, Max.


Concordo pienamente. La tua soluzione dovrebbe (dovrebbe...) risolvere il
problema (che fra l'altro anch'io non ho riscontrato).
Ciao,
--
