Sobes.tech
Middle

Cosa sono i blocchi ottimistici e pessimisti?

sobes.tech AI

Risposta dell'AI

I blocchi ottimistici e pessimistici sono approcci per gestire l'accesso parallelo ai dati condivisi in ambienti concorrenti (applicazioni multithread, database).

Blocco pessimistico:

Suppone che i conflitti nell'accesso ai dati siano probabili. Prima di accedere a una risorsa, il thread o la transazione la blocca (in modo esclusivo o condiviso). Altri thread che tentano di accedervi aspetteranno che il blocco venga rilasciato.

  • Vantaggi: Garantisce l'integrità dei dati, è semplice da implementare in ambienti con bassa concorrenza.
  • Svantaggi: Può causare blocchi (attese), ridurre la capacità di throughput in presenza di alta concorrenza (deadlock).
  • Esempi: la parola chiave synchronized in Java, blocchi a livello di riga o tabella nei database.
// Esempio di blocco pessimistico in Java
public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++; // Blocco sull'oggetto, un solo thread può eseguire questo metodo alla volta
    }

    public synchronized int getCount() {
        return count;
    }
}

Blocco ottimistico:

Suppone che i conflitti nell'accesso ai dati siano improbabili. L'accesso ai dati avviene senza blocchi. Prima di salvare, si verifica che i dati non siano stati modificati da un altro thread dall'ultima lettura. Se ci sono stati cambiamenti, l'operazione viene annullata e di solito ripetuta (retry).

  • Vantaggi: Alta capacità di throughput in ambienti con bassa concorrenza, nessun problema di deadlock.
  • Svantaggi: Possono verificarsi conflitti che richiedono ripetizioni, complicando la logica. Non adatto per operazioni di lunga durata o con alta probabilità di conflitti.
  • Esempi: operazioni Compare-And-Swap (CAS), gestione delle versioni nei database (ad esempio, uso di colonne di versione o timestamp).
// Esempio di blocco ottimistico usando CAS (java.util.concurrent.atomic)
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicCounter {
    private AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        // Tentativo di incremento atomico
        // Se il valore cambia tra la lettura e l'aggiornamento, si riprova
        count.incrementAndGet();
    }

    public int getCount() {
        return count.get();
    }
}

Confronto:

Caratteristica Blocco pessimistico Blocco ottimistico
Supposizione I conflitti sono probabili I conflitti sono improbabili
Approccio Blocco fino all'accesso Accesso senza blocco, verifica in scrittura
In ambienti ad alta concorrenza Può causare blocchi, ridurre la capacità Riconfigurazioni frequenti, ridurre le prestazioni
In ambienti a bassa concorrenza Può creare overhead Alta capacità di elaborazione
Problema di deadlock Possibile Impossibile (dal punto di vista dell'accesso concorrente alle risorse)