0Pricing
Java Academy · Lezione

Singleton: implementazioni thread-safe

Costruisca un Singleton thread-safe utilizzando il double-checked locking, un enum o il pattern holder.

Singleton: implementazioni thread-safe è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 1 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.

Il pattern Singleton

Il pattern Singleton garantisce che nella JVM esista una sola istanza di una classe. Casi d'uso comuni: gestori della configurazione, pool di connessioni e servizi di logging.

Singleton ingenuo — non thread-safe

Il Singleton lazy classico non è sicuro in caso di accesso concorrente: due thread possono superare contemporaneamente il controllo di null e creare due istanze.

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

Metodo synchronized — semplice ma lento

Aggiungere synchronized a getInstance() lo rende thread-safe, ma impone un lock a ogni chiamata, anche dopo la creazione dell'istanza, causando un overhead non necessario.

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

Doppio controllo del locking

Effettui un controllo senza lock, quindi lo ripeta all'interno di un blocco synchronized. Il campo deve avere il modificatore volatile per impedire il riordinamento delle istruzioni.

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

Holder con inizializzazione su richiesta

È il Singleton lazy più sicuro ed efficiente: una classe annidata statica privata contiene l'istanza. La JVM la carica solo alla prima chiamata di getInstance(); il caricamento delle classi è intrinsecamente thread-safe.

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

Singleton con enum

Effective Java consiglia un enum con una sola costante. È conciso, thread-safe, sicuro per la serializzazione e immune agli attacchi tramite reflection.

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

Inizializzazione eager

Se il costo di avvio è accettabile, inizializzi l'istanza al caricamento della classe con un campo static final. È una soluzione semplice e thread-safe, ma l'istanza viene sempre creata anche se non viene mai utilizzata.

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

Singleton e serializzazione

Un Singleton serializzato e poi deserializzato produce una nuova istanza, a meno che non si aggiunga readResolve() che restituisce INSTANCE. L'approccio con enum gestisce automaticamente questo caso.

private Object readResolve() { return INSTANCE; }

Singleton e attacchi tramite reflection

La reflection può invocare costruttori privati. Per difendersi, generi un'eccezione nel costruttore se esiste già un'istanza. I Singleton basati su enum sono immuni secondo la specifica della JVM.

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

Singleton nei framework di dependency injection

In Spring, i bean sono singleton per impostazione predefinita (@Scope("singleton")). Raramente è necessario implementare manualmente il pattern Singleton: lasci che sia il contenitore DI a gestirlo.

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

Test dei singleton

I singleton sono difficili da sottoporre a unit test perché conservano uno stato globale. Preferisca la dependency injection al codice Singleton manuale; nei test, inietti istanze mock tramite l'iniezione nel costruttore.

Verifica rapida

Quale approccio al Singleton è consigliato in Effective Java?

Riepilogo

Per i singleton thread-safe, utilizzi l'approccio Initialization-on-Demand Holder oppure quello basato su enum. Eviti l'inizializzazione lazy ingenua. Nelle applicazioni Spring, lasci che sia il framework a gestire l'ambito.

Domande Frequenti

La lezione «Singleton: implementazioni thread-safe» è gratuita?

Sì — il testo completo di «Singleton: implementazioni thread-safe» è 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 «Singleton: implementazioni thread-safe»?

Costruisca un Singleton thread-safe utilizzando il double-checked locking, un enum o il pattern holder. 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 1 di 4.

Quanto tempo richiede la lezione «Singleton: implementazioni thread-safe»?

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. Singleton: implementazioni thread-safe
  2. Pattern Factory Method
  3. Abstract Factory per famiglie di prodotti
  4. Pattern Builder con API fluent
← Torna a Java Academy