Java Academy · Lektion

Singleton: trådsäkra implementationer

Bygg en trådsäker Singleton med dubbelkontrollerad låsning, enum eller holder-mönstret.

Lektion 1 av 413 steg

Singleton: trådsäkra implementationer är en gratis lektion i Java Academy på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Java Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Java Academy innehåller totalt 4 lektioner.

Singleton-mönstret

Singleton-mönstret säkerställer att det bara finns en instans av en klass i JVM:en. Vanliga användningsområden är konfigurationshanterare, anslutningspooler och loggningstjänster.

Naiv Singleton – inte trådsäker

Den klassiska lata singleton-implementeringen fungerar inte vid samtidiga åtkomster: två trådar kan båda passera null-kontrollen samtidigt och skapa två instanser.

public class Config {
    private static Config instance;
    private Config() {}
    public static Config getInstance() {
        if (instance == null) {              // race condition!
            instance = new Config();
        }
        return instance;
    }
}

Synkroniserad metod – enkel men långsam

Att lägga till synchronized i getInstance() gör metoden trådsäker men låser vid varje anrop, även efter att instansen har skapats – en onödig overhead.

public static synchronized Config getInstance() {
    if (instance == null) instance = new Config();
    return instance;
}

Dubbelkontrollerad låsning

Kontrollera utan lås och kontrollera sedan igen i ett synchronized-block. Fältet måste ha volatile för att förhindra att instruktioner ordnas om.

public class Config {
    private static volatile Config instance;
    private Config() {}
    public static Config getInstance() {
        if (instance == null) {
            synchronized (Config.class) {
                if (instance == null) instance = new Config();
            }
        }
        return instance;
    }
}

Initialization-on-Demand Holder

Den säkraste och mest effektiva lata Singleton-implementeringen: en privat statisk nästlad klass innehåller instansen. JVM:en laddar den först när getInstance() anropas första gången – klassladdning är trådsäker i sig.

public class Config {
    private Config() {}
    private static final class Holder {
        static final Config INSTANCE = new Config();
    }
    public static Config getInstance() {
        return Holder.INSTANCE;
    }
}

Enum Singleton

Effective Java rekommenderar en enum med en enda konstant. Det är kortfattat, trådsäkert, säkert vid serialisering och immunt mot reflektionsattacker.

public enum AppConfig {
    INSTANCE;
    private String apiUrl = "https://api.example.com";
    public String getApiUrl() { return apiUrl; }
}
// Usage:
String url = AppConfig.INSTANCE.getApiUrl();

Omedelbar initiering

Om kostnaden vid uppstart är acceptabel kan instansen initieras när klassen laddas, med ett static final-fält. Det är enkelt och trådsäkert, men instansen skapas alltid även om den aldrig används.

public class Config {
    private static final Config INSTANCE = new Config();
    private Config() {}
    public static Config getInstance() { return INSTANCE; }
}

Singleton och serialisering

En singleton som serialiseras och sedan deserialiseras ger upphov till en ny instans om inte readResolve() läggs till och returnerar INSTANCE. Enum-metoden hanterar detta automatiskt.

private Object readResolve() { return INSTANCE; }

Singleton och reflektionsattacker

Reflection kan anropa privata konstruktorer. Skydda mot detta genom att kasta ett undantag i konstruktorn om en instans redan finns. Enum-singletonobjekt är immuna enligt JVM-specifikationen.

private Config() {
    if (Holder.INSTANCE != null) {
        throw new IllegalStateException("Use getInstance()");
    }
}

Singleton i ramverk för dependency injection

I Spring är beans singletonobjekt som standard (@Scope("singleton")). Singleton-mönstret implementeras sällan manuellt; låt DI-containern hantera det.

@Component  // Spring manages a single instance
public class FeatureFlags {
    private final boolean darkMode = true;
    public boolean isDarkMode() { return darkMode; }
}

Testa Singleton-objekt

Singleton-objekt är svåra att enhetstesta eftersom de innehåller globalt tillstånd. Föredra dependency injection framför manuell Singleton-kod och injicera mockinstanser i tester via konstruktorinjektion.

Snabbkontroll

Vilken Singleton-metod rekommenderas i Effective Java?

Sammanfattning

För trådsäkra singleton-objekt: använd Initialization-on-Demand Holder eller enum-metoden. Undvik naiv lazy-initialisering. Låt ramverket hantera scope-hanteringen i Spring-applikationer.

Gratis att börja

Lär dig Java med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
104
Lektioner
374

Vanliga frågor

Är lektionen ”Singleton: trådsäkra implementationer” gratis?

Ja – hela texten till ”Singleton: trådsäkra implementationer” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Java Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Java Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Singleton: trådsäkra implementationer”?

Bygg en trådsäker Singleton med dubbelkontrollerad låsning, enum eller holder-mönstret. Ni övar på Java Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Java Academy?

Du behöver inga förkunskaper. Utbildningen i Java Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Singleton: trådsäkra implementationer”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Java Academy-lektionen?

Ja. Varje Java Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Singleton: trådsäkra implementationer
  2. Fabrikmetodmönstret
  3. Abstrakt fabrik för produktfamiljer
  4. Builder-mönstret med fluent-API
← Tillbaka till Java Academy