0Pricing
Java Academy · Lezione

StampedLock e letture ottimistiche

Applichi la modalità di lettura ottimistica di StampedLock in carichi di lavoro ad alto throughput e dominati dalle letture.

StampedLock e letture ottimistiche è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

Che cos'è StampedLock?

Introdotto in Java 8, StampedLock estende i concetti di ReadWriteLock con un'ulteriore modalità di lettura ottimistica. Le operazioni restituiscono uno stamp long usato per rilasciare il lock o convalidare la lettura ottimistica.

import java.util.concurrent.locks.*;

StampedLock sl = new StampedLock();

// Exclusive write:
long stamp = sl.writeLock();
try {
    // write data
} finally {
    sl.unlockWrite(stamp);
}

// Shared read:
stamp = sl.readLock();
try {
    // read data
} finally {
    sl.unlockRead(stamp);
}

Modalità di lettura ottimistica

La lettura ottimistica non acquisisce alcun lock: ottiene soltanto uno stamp. Dopo la lettura, convalidare lo stamp. Se la convalida fallisce (perché è intervenuto uno scrittore), passare a un vero read lock:

StampedLock sl2 = new StampedLock();
double x = 0, y = 0;

// Try optimistic read first:
long stamp = sl2.tryOptimisticRead();
double localX = x, localY = y; // read values

if (!sl2.validate(stamp)) {
    // A write occurred — fall back to read lock
    stamp = sl2.readLock();
    try {
        localX = x;
        localY = y;
    } finally {
        sl2.unlockRead(stamp);
    }
}
// use localX and localY

Esempio completo con Point2D

Esempio classico di StampedLock: un punto 2D con letture ottimistiche:

class Point {
    private double x, y;
    private final StampedLock lock = new StampedLock();
    
    void move(double dx, double dy) {
        long stamp = lock.writeLock();
        try { x += dx; y += dy; }
        finally { lock.unlockWrite(stamp); }
    }
    
    double distanceFromOrigin() {
        long stamp = lock.tryOptimisticRead();
        double cx = x, cy = y;
        if (!lock.validate(stamp)) {
            stamp = lock.readLock();
            try { cx = x; cy = y; }
            finally { lock.unlockRead(stamp); }
        }
        return Math.sqrt(cx * cx + cy * cy);
    }
}

Conversione del lock

StampedLock supporta la conversione tra le modalità di lock:

StampedLock sl3 = new StampedLock();

// Read → Write upgrade attempt:
long readStamp = sl3.readLock();
long writeStamp = sl3.tryConvertToWriteLock(readStamp);
if (writeStamp != 0) {
    // Successfully upgraded!
    // ... write ...
    sl3.unlockWrite(writeStamp);
} else {
    // Upgrade failed — release read and reacquire write
    sl3.unlockRead(readStamp);
    writeStamp = sl3.writeLock();
    // ... write ...
    sl3.unlockWrite(writeStamp);
}

Quando le letture ottimistiche sono più utili

Le letture ottimistiche sono particolarmente efficaci quando:

  • Le letture sono molto più frequenti delle scritture
  • Lo snapshot dei dati può essere contenuto in poche variabili locali (senza allocazione di oggetti)
  • La contesa sulle scritture è ridotta (la convalida fallisce raramente)

Se le scritture sono frequenti, le letture ottimistiche passano ripetutamente a read lock completi, senza offrire alcun vantaggio.

StampedLock e ReadWriteLock a confronto

Differenze principali:

  • StampedLock: aggiunge le letture ottimistiche; NON è rientrante e non supporta Condition
  • ReentrantReadWriteLock: è rientrante, supporta Condition e non offre una modalità ottimistica

StampedLock è più veloce quando la contesa sulle scritture è ridotta. ReentrantReadWriteLock è più sicuro e offre più funzionalità.

StampedLock NON è rientrante

A differenza di ReentrantLock, StampedLock NON è rientrante. Un thread che tenta di acquisire una modalità già detenuta causa un deadlock:

StampedLock sl4 = new StampedLock();
long s1 = sl4.readLock();
// DO NOT: sl4.readLock() again — deadlocks with non-reentrant!

tryWriteLock e tryReadLock

I tentativi di acquisizione non bloccanti restituiscono 0 se non riescono:

StampedLock sl5 = new StampedLock();

long stamp = sl5.tryWriteLock();
if (stamp != 0) {
    try {
        System.out.println("Got write lock");
    } finally {
        sl5.unlockWrite(stamp);
    }
} else {
    System.out.println("Write lock unavailable");
}

Usarlo come ReadWriteLock

Per garantire la compatibilità, StampedLock può restituire una vista come ReadWriteLock standard:

StampedLock sl6 = new StampedLock();
Lock readLock  = sl6.asReadLock();
Lock writeLock = sl6.asWriteLock();
ReadWriteLock rwView = sl6.asReadWriteLock();
// These provide standard Lock interface without optimistic mode

Indicazioni sul benchmark delle prestazioni

I risultati dei benchmark mostrano in genere:

  • Carico con prevalenza molto elevata di letture (99% di letture): StampedLock > ReadWriteLock > synchronized
  • Carico misto (70% di letture): ReadWriteLock ≈ StampedLock
  • Carico con prevalenza di scritture: spesso synchronized o ReentrantLock risultano migliori (minore overhead)

Eseguire sempre il profiling con carichi di lavoro realistici prima di ottimizzare.

Invalidità dello stamp dopo il rilascio del lock

Dopo aver rilasciato un lock con uno stamp, lo stamp diventa non valido. Usare uno stamp precedente dopo il rilascio del lock comporta un comportamento indefinito: acquisire sempre uno stamp aggiornato per ogni acquisizione del lock.

StampedLock sl7 = new StampedLock();
long stamp = sl7.writeLock();
sl7.unlockWrite(stamp);
// stamp is now invalid — don't use it:
// sl7.unlockWrite(stamp); // throws IllegalMonitorStateException or corrupts state

Verifica rapida

Una lettura ottimistica con tryOptimisticRead() e una successiva validate(stamp) restituisce false. Che cosa dovrebbe fare il codice a questo punto?

Riepilogo: StampedLock

Punti chiave:

  • Tre modalità: lettura ottimistica (senza lock), read lock e write lock
  • tryOptimisticRead() + validate(): tentativo di lettura a costo zero
  • In caso di convalida fallita → passare a readLock()
  • NON è rientrante: rischio di deadlock se lo stesso thread lo acquisisce nuovamente
  • Non supporta Condition: usare ReentrantReadWriteLock quando necessario

Domande Frequenti

La lezione «StampedLock e letture ottimistiche» è gratuita?

Sì — il testo completo di «StampedLock e letture ottimistiche» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «StampedLock e letture ottimistiche»?

Applichi la modalità di lettura ottimistica di StampedLock in carichi di lavoro ad alto throughput e dominati dalle letture. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «StampedLock e letture ottimistiche»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. ReentrantLock e synchronized a confronto
  2. ReadWriteLock per scenari lettore-scrittore
  3. Variabili atomiche: aggiornamenti senza lock
  4. StampedLock e letture ottimistiche
← Torna a Java Academy