|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
[Java] synchronization
perché questo codice
class Prova { public static Object obj = new Object(); public static String s = "0"; public static void main(String[] args) { // creo 2 thread che eseguano il run di Incrementor // aspetto che i 2 thread terminino // stampo il valore di s } } class Incrementor implements Runnable { public void run() { for (i = 0; i < 1000000; i++) { synchronized(Prova.s) { s = "" + (Integer.parseInt(Prova.s) + 1); } } } } porta a un valore finale di s errato mentre se mi sincronizzo su Prova.obj invece che su Prova.s funziona correttamente? |
![]() |
![]() |
![]() |
#2 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Ma il fatto è che mentre il reference obj è e rimane fisso, il reference alla stringa cambia per via della concatenazione! Per tale motivo non va bene.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
mille grazie!
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
synchronized(Prova.s) {
s = "" + (Integer.parseInt(Prova.s) + 1); } è la priva volta che vedo questo tipo di codice,ma cosa fa esattamente? |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
synchronized è la parola chiave che permette di gestire una "mutua esclusione" tra più thread. Ogni oggetto ha un monitor, di cui un thread può fare il lock e unlock. Solo un thread per volta può acquisire il lock sul monitor. Gli altri eventuali thread che cercano di acquisire il lock su un monitor già lockato, sono bloccati fino a quando viene fatto l'unlock sul monitor.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
la parola chiave "synchronized" stabilisce che il metodo o, nel caso in questione, il blocco di codice è ad accesso mutualmente esclusivo.
Gli esclusi sono i Thread: solo un Thread alla volta può trovarsi all'interno di quel blocco (ad eseguirne il contenuto). La mutualità è prodotta attraverso un monitor, cioè un valore di controllo che dice "in questo istante sono posseduto da qualcuno". Stile esorcista. Ai fini della sincronizzazione, ogni Object Java è un monitor. Cioè tutto tranne i primitivi. Bene, quella forma: Codice:
synchronized(qualcosa) { } Il monitor viene rilasciato automaticamente all'uscita, comunque motivata, dal blocco sincronizzato. La forma: Codice:
synchronized { } Codice:
synchronized(this) { } synchronized void unMetodo() { ...contenuto del metodo } Equivale a: Codice:
void unMetodo() { synchronized { ...contenuto del metodo } }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
Quote:
Poi si discuteva sulla stringa:è ver che con la concatenazione in realtà si passa a referenziare un nuovo oggetto ma non capisco come mai fallisca il metodo. s all' inizio punterà a "ciao" poi se si concatena punterà ad un nuovo oggetto " ciao ciao" ma perchè si ha il problema sulla sincronizzazione? |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
E be', e dammi una mano andbin! Se mi scrivi quattro righe è chiaro che duplico le risposte! E prenditi un po' di tempo!
![]()
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#9 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
il lock su cui gli statement synchronized si sincronizzano credo non c'entri nulla col monitor di un oggetto, che sarebbe invece quello su cui si sincronizzano i metodi wait, notify, notifyAll... sono due meccanismi indipendenti.
|
![]() |
![]() |
![]() |
#11 |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
|
![]() |
![]() |
![]() |
#12 | |
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
![]() a questa domanda tu avresti risposto di si, e io subito dopo avrei chiesto: "ma allora a che serve notifyAll dato che un solo thread alla volta può chiamare wait?", ma ho letto ora che wait rilascia il monitor ^^ |
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Oct 2006
Messaggi: 1105
|
[edit] ti sei già risposto
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 7863
|
bisogna chiamare syncronized prima di wait?
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Bisogna invocare wait() all'interno di un blocco sincronizzato sull'oggetto che subisce l'invocazione di wait().
Cioè se: x.wait(); allora dev'essere: Codice:
synchronized(x) { x.wait(); } Codice:
synchronized { wait(); }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#16 |
Messaggi: n/a
|
c'è un modo non bloccante per vedere se il monitor di un certo oggetto è già sotto il controllo di un Thread?
|
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
C'è il metodo holdsLock di Thread che però non dice se sia o non sia bloccante, cioè se il controllo sia fatto tentando un'acquisizione del monitor.
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#18 | ||
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
All'inizio si ha un oggetto "0". I thread <A> e <B> cercano di ottenere il lock su "0". <A> ad esempio ci riesce ed esegue il blocco, mentre <B> rimane bloccato sempre su "0". <A> crea un nuovo oggetto "1" e cambia il reference. <B> rimane ancora bloccato su "0" (che esiste ancora ... non è sparito). <A> rilascia il lock su "0" e quindi <B> può ottenere il lock su "0" (che era in attesa). Ma intanto 's' è cambiato quindi <A> cerca di fare il lock su "1" e non più "0". Alla fine della storia che succede? Che ci può essere un istante in cui entrambi i thread entrano nel blocco perché hanno il lock su oggetti diversi. E questo è moooolto pericoloso! ![]() Quote:
![]() ![]() Ehm .. non c'è la forma breve. La parte (Espressione) ci deve sempre essere.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
||
![]() |
![]() |
![]() |
#19 |
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Sì, pardon, intendevo la forma:
Codice:
synchronized void blabla() { } Codice:
void blabla { synchronized(blu) { } }
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me! |
![]() |
![]() |
![]() |
#20 |
Member
Iscritto dal: Dec 2005
Messaggi: 119
|
scusate ragazzi una domandina..se invoco il metodo wait() lo devo sempre includere in un blocco synchronized??(ovviamente oltre a gestire l'eccezione)
__________________
Meglio? |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 09:20.