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

    [JAVA] Sincronizzazione vs Condition

    La differenza tra l'uso di synchronized e l'uso di Lock e Condition sta nel fatto che nel primo caso si usa il lock implicito dell'oggetto e nel secondo caso quello esplicito.

    Ma a parte questa differenza, qual'è il vero vantaggio, se esiste, di usare un tipo di sincronjizzazione esplicita piuttosto che implicita?

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

    Re: [JAVA] Sincronizzazione vs Condition

    Originariamente inviato da ragnonerodocet
    La differenza tra l'uso di synchronized e l'uso di Lock e Condition sta nel fatto che nel primo caso si usa il lock implicito dell'oggetto e nel secondo caso quello esplicito.

    Ma a parte questa differenza, qual'è il vero vantaggio, se esiste, di usare un tipo di sincronjizzazione esplicita piuttosto che implicita?
    Lock innanzitutto è una interfaccia, quindi si userà sempre una implementazione concreta di tale interfaccia, tipicamente ReentrantLock.

    Comunque i Lock non sono un "rimpiazzamento" del lock intrinseco, semmai sono un meccanismo di lock alternativo che fornisce delle funzionalità più avanzate. Il lock intrinseco va bene in molte situazioni abbastanza comuni ma ha delle limitazioni. Ad esempio quando il thread è nella fase di wait per la acquisizione del lock, non puoi interromperlo. E ad esempio non puoi nemmeno imporre un tempo massimo per il wait. Cose che invece puoi fare con ReentrantLock. E non è tutto qui, comunque.

    Condition invece è un'altra cosa. Per fare un rapporto: i Lock sono una generalizzazione del intrinsic lock così come i Condition sono una generalizzazione del meccanismo di wait/notify associato al intrinsic lock.

    Se ti piacciono/interessano queste cose, ti posso consigliare il libro: Java Concurrency in Practice. Io ce l'ho, l'ho letto di recente e devo dire che è davvero ottimo e validissimo. Purtroppo non l'ho trovato "facile" da leggere, sia per gli argomenti di livello davvero elevato, sia per lo stile di scrittura, con frasi molto lunghe, descrittive e anche un po' "forbite".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Ho preso il libro...

    Comunque mi interessava avere un'altra informazione sempre relativa alla serializzazione.

    Ogni oggetto ha un lock intrinseco, che posso manovrare implicitamente con la parola chiave

    synchronized

    che può riferirsi ad un oggetto o ad un metodo.

    Se dichiaro

    synchronized (Object o)

    un qualsiasi tentativo da parte di un thread di accedere all'oggetto mediante un metodo dello stesso sarà impossibile. Dunque il Thread che trova il lock chiuso rimarrà in coda finchè il lock intrinseco non sarà libero.

    Se dichiaro un metodo synchronized invece, cosa accade?

    La stessa identica cosa di prima oppure qualcosa di diverso?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da ragnonerodocet
    Ogni oggetto ha un lock intrinseco, che posso manovrare implicitamente con la parola chiave

    synchronized

    che può riferirsi ad un oggetto o ad un metodo.
    La parola chiave 'synchronized' la puoi applicare ad un metodo (di istanza o di classe) o la puoi usare per racchiudere un blocco con il lock indicato da una espressione che deve essere chiaramente un reference.

    Se il synchronized è su un metodo di istanza, il "lock" è l'oggetto stesso su cui è stato invocato il metodo.

    Se il synchronized è su un metodo di classe, il "lock" è l'oggetto Class relativo alla classe.

    Se il synchronized è su un blocco, il "lock" è l'oggetto indicato esplicitamente.


    Quindi fare:

    public synchronized void pippo () { ... }

    è equivalente a:

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

    mentre fare:

    public static synchronized void pippo () { ... }

    è equivalente a:

    public static void pippo () {
    synchronized (NomeClasse.class) { .... }
    }

    Ho detto "equivalente" perché hanno esattamente lo stesso identico effetto ma per il bytecode generato chiaramente non è la stessa identica cosa. La differenza però non è rilevante/importante.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    public void pippo () {
    synchronized (this) { .... }
    }

    E in questo caso this non è un reference all'oggetto stesso?

    E comunque, domanda probabiolmente stupida...

    Ho un oggetto di classe A che chiamo pippo.

    Tale classe ha 2 metodi dichiarati synchronized. Chiamiamoli metodoA e metodoB.

    Poi istanzio su 2 thread, chiamati threadA e threadB.

    Diciamo che il threadA fa accesso al metodoA.

    Di seguito, il threadB prova a fare l'accesso al metodoB.

    Trova il lock occupato.

    Perchè il lock implicito dell'oggetto pippo è stato chiuso dal ThreadA...

    Terminato il ThreadA, il lock si sblocca e il ThreadB avrà accesso al'oggetto...

    VERO????????

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da ragnonerodocet
    public void pippo () {
    synchronized (this) { .... }
    }

    E in questo caso this non è un reference all'oggetto stesso?
    Sì, appunto. È equivalente a mettere il synchronized sul metodo.

    Originariamente inviato da ragnonerodocet
    Terminato il ThreadA, il lock si sblocca e il ThreadB avrà accesso al'oggetto...
    Quando si usa il lock intrinseco, la questione fondamentale è solo quella di capire e determinare quale è l'oggetto che fa da "lock".

    Se 2 thread invocano lo stesso metodo di istanza o metodi diversi di istanza (synchronized chiaramente) sullo stesso identico oggetto, allora il lock è lo stesso. Quindi si ha la mutua esclusione.

    Se thread1 invoca oggetto.metodoA() e il thread2 invoca oggetto.metodoB(), se l'oggetto è appunto lo stesso, c'è la mutua esclusione, ovvero essendo lo stesso lock, le due invocazioni non possono essere concorrenti. Uno dei due deve aspettare per poter acquisire il lock.

    Se gli oggetti fossero diversi, il lock non sarebbe lo stesso, quindi non ci sarebbe alcuna "serializzazione".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    E' per questo che serve la classe Condition?

    Mi spiego meglio...

    Ci hanno detto in aula che mediante Condition posso creare virtualmente più code per lo stesso oggetto, nel senso che i metodi dello stesso non avranno più un solo singolo lock da gestire implicitamente mediante synchronized, ma più lock, a seconda del numero di Condition che metto...

    E' giusto o c'è qualche falla nel mio ragionamento?

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.