O que é?

Singleton é um padrão de projeto criacional, a ideia é criar uma unica instancia que será compartilhada por N outras instancias, tendo um ponto de acesso unico

Essa instancia vai ser guardada no Heap da JVM onde ela só sera encerrada pelo garbage collector(GC) quando a aplicação for finalizada

Atenção no construtor privado para que não seja possível criação de novas instancias.


Exemplo

public class Singleton {

    private static Singleton instance;

    private Integer value;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
          instance = new Singleton();        
         }

        return instance;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public Integer getValue() {
        return value;
    }
}

Concorrência

Esse código trata corretamente da concorrência, usando o padrão conhecido como Double-Checked Locking.

Isso garante que a instância seja criada uma única vez mesmo em ambientes com múltiplas threads.

Imagine que seu Singleton representa, por exemplo, a cotação atual do dólar:

Se duas requisições simultâneas alterarem esse valor sem controle, você pode ter dados inconsistentes.

Com synchronized e volatile, isso é evitado de forma segura.

public class Singleton {

    private static volatile Singleton instance;

    private Integer value;

    private Singleton() {}

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

    public void setValue(Integer value) {
        this.value = value;
    }

    public Integer getValue() {
        return value;
    }
}