Java Academy · Lektion

StampedLock og optimistiske læsninger

Anvend StampedLocks optimistiske læsetilstand til arbejdsbelastninger med høj gennemstrømning og mange læsninger.

Lektion 4 af 413 trin

StampedLock og optimistiske læsninger er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.

Hvad er StampedLock

StampedLock blev introduceret i Java 8 og udvider ReadWriteLock-koncepterne med en ekstra tilstand for optimistisk læsning. Operationerne returnerer et langt stempel, som bruges til at frigive låsen eller validere den optimistiske læsning.

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);
}

Tilstanden optimistisk læsning

Optimistisk læsning erhverver ingen lås — den henter blot et stempel. Validér stemplet efter læsningen. Hvis valideringen mislykkes (en skriver nåede ind imellem), skal du falde tilbage til en rigtig læselås:

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

Komplet Point2D-eksempel

Klassisk StampedLock-eksempel — et 2D-punkt med optimistiske læsninger:

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);
    }
}

Konvertering mellem låsetilstande

StampedLock understøtter konvertering mellem låsetilstande:

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);
}

Hvornår er optimistisk læsning mest nyttig

Optimistisk læsning er særligt effektiv, når:

  • Der er langt flere læsninger end skrivninger
  • Datasnapshotten kan rummes i nogle få lokale variabler (uden objektallokering)
  • Konkurrencen om skrivelåsen er lav (valideringen mislykkes sjældent)

Hvis skrivninger forekommer ofte, falder optimistiske læsninger gentagne gange tilbage til fulde læselåse — uden at give nogen fordel.

StampedLock kontra ReadWriteLock

Vigtige forskelle:

  • StampedLock: tilføjer optimistiske læsninger; understøtter IKKE genindtræden; ingen understøttelse af Condition
  • ReentrantReadWriteLock: understøtter genindtræden og Conditions; ingen optimistisk tilstand

StampedLock er hurtigere ved lav konkurrence om skrivelåsen. ReentrantReadWriteLock er sikrere og har flere funktioner.

StampedLock understøtter IKKE genindtræden

I modsætning til ReentrantLock understøtter StampedLock IKKE genindtræden. En tråd, der forsøger at erhverve en tilstand, som den allerede holder, skaber deadlock:

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

tryWriteLock og tryReadLock

Forsøg på erhvervelse uden blokering returnerer 0, hvis det mislykkes:

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");
}

Brug som ReadWriteLock

StampedLock kan returnere en visning som en standard-ReadWriteLock af hensyn til kompatibilitet:

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

Intuition for ydeevnebenchmark

Benchmarkresultater viser typisk:

  • Meget læsetung arbejdsbelastning (99 % læsninger): StampedLock > ReadWriteLock > synchronized
  • Blandet arbejdsbelastning (70 % læsninger): ReadWriteLock ≈ StampedLock
  • Skrivetung arbejdsbelastning: synchronized eller ReentrantLock vinder ofte (mindre overhead)

Mål altid ydeevnen med realistiske arbejdsbelastninger, før du optimerer.

Ugyldigt stempel efter frigivelse af låsen

Efter frigivelse af en lås med et stempel bliver stemplet ugyldigt. Brug af et gammelt stempel efter frigivelsen medfører udefineret adfærd — hent altid et nyt stempel for hver erhvervelse af låsen.

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

Hurtigt tjek

En optimistisk læsning med tryOptimisticRead() efterfulgt af validate(stamp) returnerer false. Hvad skal koden gøre derefter?

Opsummering: StampedLock

Vigtige pointer:

  • Tre tilstande: optimistisk læsning (ingen lås), læselås og skrivelås
  • tryOptimisticRead() + validate() — læseforsøg uden omkostning
  • Ved mislykket validering → fald tilbage til readLock()
  • Understøtter IKKE genindtræden — risiko for deadlock, hvis den samme tråd erhverver låsen igen
  • Ingen understøttelse af Condition — brug ReentrantReadWriteLock, når det er nødvendigt
Gratis at komme i gang

Lær Java med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
104
Lektioner
374

Ofte stillede spørgsmål

Er lektionen “StampedLock og optimistiske læsninger” gratis?

Ja — hele teksten til “StampedLock og optimistiske læsninger” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “StampedLock og optimistiske læsninger”?

Anvend StampedLocks optimistiske læsetilstand til arbejdsbelastninger med høj gennemstrømning og mange læsninger. Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Java Academy?

Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “StampedLock og optimistiske læsninger”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Java Academy-lektion?

Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. ReentrantLock vs. synchronized
  2. ReadWriteLock til læser-skriver-scenarier
  3. Atomare variabler: opdateringer uden låse
  4. StampedLock og optimistiske læsninger
← Tilbage til Java Academy