Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    [JAVA] java.util.concurrent.locks

    Sul sito della sun, nella definizione dell'interfaccia Lock, ho trovato questa definizione che mi ha un po' spiazzato...

    con synchronized, quando più lock sono acquisiti, devono essere rilasciati nell'esatto ordine opposto, e devono essere rilasciati nella stessa "portata lessicale" (lexical scope) nella quale sono stati acquisiti.
    L'implementazione di Lock permette invece di acquisire e rilasciare il lock in diversi "scopes" e permette l'acquisizione e il rilascio di lock multipli in qualsiasi ordine.

    Qualcuno potrebbe spiegarmi meglio questa differenza?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [JAVA] java.util.concurrent.locks

    Originariamente inviato da ragnonerodocet
    con synchronized, quando più lock sono acquisiti, devono essere rilasciati nell'esatto ordine opposto, e devono essere rilasciati nella stessa "portata lessicale" (lexical scope) nella quale sono stati acquisiti.
    L'implementazione di Lock permette invece di acquisire e rilasciare il lock in diversi "scopes" e permette l'acquisizione e il rilascio di lock multipli in qualsiasi ordine.
    Con la parola chiave synchronized, il lock viene acquisito quando si entra nel metodo/blocco synchronized e viene rilasciato quando si esce dal metodo/blocco synchronized. Quindi è ovvio che c'è un ordine ben preciso di acquisizione e rilascio che dipende dall'annidamento delle acquisizioni.

    codice:
    synchronized(oggetto1) {
        synchronized(oggetto2) {
            ...
        }
    }
    Qui è chiaro che prima acquisisce il lock su oggetto1, poi su oggetto2, quindi terminato il blocco interno rilascia il lock su oggetto2 e terminato il blocco esterno rilascia il lock su oggetto1.

    In pratica la sequenza di acquisizione/rilascio dipende dalla struttura del codice, cioè dall'annidamento di blocchi o di invocazioni di metodi. E non può essere altrimenti.

    Con i Lock in java.util.concurrent.locks non si ha questo limite, le acquisizioni/rilasci sono fatte invocando appositi metodi sui Lock, quindi si possono fare con sequenze diverse e in contesti diversi.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Mamma mia, che ignorante...

    Nella mia brada conoscenza del multithreading non avevo pensato che si, pu; esserci solo un thread in esecuzione, ma tale Thread pu; acquisire pi\ lock da oggetti diversi.

    Cosa accade se, nell-esempio da Lei fatto, provo con la parola synchronized ad acquisire 2 volte il lock dello stesso oggetto?

    public synchronized (this) {
    public synchronized(this) {
    ...
    }
    }

    Errore a runtime di che tipo?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da ragnonerodocet
    Cosa accade se, nell-esempio da Lei fatto, provo con la parola synchronized ad acquisire 2 volte il lock dello stesso oggetto?

    public synchronized (this) {
    public synchronized(this) {
    ...
    }
    }

    Errore a runtime di che tipo?
    Nessun errore! Anzi se avessero scelto/stabilito che era una errore, sarebbe stato un gran macello!!!!

    Immagina una situazione:

    codice:
    public synchronized void pippo () { ... }
    
    public synchronized void pluto () {
        pippo();
    }
    Anche qui ci sarebbe l'acquisizione del lock su 'this' annidata 2 volte.

    La gestione degli intrinsic lock è reentrant (rientrante). Cioè se un thread cerca di acquisire un lock che già possiede, non ci sono problemi e la acquisizione ha immediatamente successo.
    Per il lock vengono mantenuti 2 dati: un contatore e un reference al thread "owner" (proprietario). Se il lock non è di nessuno, il contatore è 0. Se un thread acquisisce il lock, il contatore diventa 1 e viene memorizzato l'owner. Se un thread cerca di acquisire un lock che già possiede, la JVM se ne accorge (il thread è associato al lock) ed incrementa semplicemente il contatore. Ad ogni rilascio il contatore viene decrementato. Questo permette appunto la "rientranza".

    E nota che ReentrantLock, lo dice il nome stesso, è pure lui "rientrante".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.