Singleton: Implementações Seguras para Threads
Crie um Singleton seguro para threads usando bloqueio com verificação dupla, enumeração ou o padrão holder.
Singleton: Implementações Seguras para Threads é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
O Padrão de Instância Única
O padrão de instância única garante que exista apenas uma instância de uma classe na JVM. Casos de uso comuns: gerenciadores de configuração, conjuntos de conexões e serviços de registro.
Instância Única Ingênua — Não Segura para Execução Concorrente
A instância única clássica com inicialização preguiçosa falha sob acesso concorrente: duas threads podem passar simultaneamente pela verificação de nulo e criar duas instâncias.
public class Config {
private static Config instance;
private Config() {}
public static Config getInstance() {
if (instance == null) { // race condition!
instance = new Config();
}
return instance;
}
}Método Sincronizado — Simples, mas Lento
Adicionar synchronized a getInstance() torna o método seguro para execução concorrente, mas bloqueia cada chamada, mesmo depois que a instância existe — uma sobrecarga desnecessária.
public static synchronized Config getInstance() {
if (instance == null) instance = new Config();
return instance;
}Bloqueio com Verificação Dupla
Faça uma verificação sem bloqueio e, em seguida, verifique novamente dentro de um bloco synchronized. O campo precisa de volatile para impedir a reordenação de instruções.
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;
}
}Inicialização por Classe Holder sob Demanda
A instância única com inicialização preguiçosa mais segura e eficiente: uma classe aninhada estática privada mantém a instância. A JVM só a carrega quando getInstance() é chamado pela primeira vez — o carregamento de classes é inerentemente seguro para execução concorrente.
public class Config {
private Config() {}
private static final class Holder {
static final Config INSTANCE = new Config();
}
public static Config getInstance() {
return Holder.INSTANCE;
}
}Instância Única com Enumeração
O livro Effective Java recomenda uma enumeração com uma única constante. É concisa, segura para execução concorrente, segura para serialização e imune a ataques de reflexão.
public enum AppConfig {
INSTANCE;
private String apiUrl = "https://api.example.com";
public String getApiUrl() { return apiUrl; }
}
// Usage:
String url = AppConfig.INSTANCE.getApiUrl();Inicialização Antecipada
Se o custo de inicialização for aceitável, inicialize a instância no momento do carregamento da classe com um campo static final. É simples e segura para execução concorrente, mas a instância será sempre criada, mesmo que nunca seja usada.
public class Config {
private static final Config INSTANCE = new Config();
private Config() {}
public static Config getInstance() { return INSTANCE; }
}Instância Única e Serialização
Uma instância única serializada e depois desserializada produz uma nova instância, a menos que você adicione readResolve() retornando INSTANCE. A abordagem com enumeração lida com isso automaticamente.
private Object readResolve() { return INSTANCE; }Instância Única e Ataques de Reflexão
A reflexão pode chamar construtores privados. Defenda-se lançando uma exceção no construtor caso já exista uma instância. Instâncias únicas baseadas em enumeração são imunes segundo a especificação da JVM.
private Config() {
if (Holder.INSTANCE != null) {
throw new IllegalStateException("Use getInstance()");
}
}Instância Única em Estruturas de Injeção de Dependências
No Spring, os componentes são instâncias únicas por padrão (@Scope("singleton")). Raramente é necessário implementar manualmente o padrão de instância única; deixe o contêiner de DI gerenciá-lo.
@Component // Spring manages a single instance
public class FeatureFlags {
private final boolean darkMode = true;
public boolean isDarkMode() { return darkMode; }
}Testando Instâncias Únicas
Instâncias únicas são difíceis de testar em testes unitários porque mantêm estado global. Prefira a injeção de dependências ao código manual de instância única; injete instâncias simuladas nos testes por meio da injeção pelo construtor.
Verificação Rápida
Qual abordagem de instância única é recomendada no Effective Java?
Recapitulação
Para instâncias únicas seguras para execução concorrente, use a abordagem de inicialização por classe Holder sob demanda ou a abordagem com enumeração. Evite a inicialização preguiçosa ingênua. Em aplicações Spring, deixe a estrutura cuidar do gerenciamento do escopo.
Perguntas Frequentes
A aula “Singleton: Implementações Seguras para Threads” é grátis?
Sim — o texto completo de “Singleton: Implementações Seguras para Threads” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “Singleton: Implementações Seguras para Threads”?
Crie um Singleton seguro para threads usando bloqueio com verificação dupla, enumeração ou o padrão holder. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Singleton: Implementações Seguras para Threads”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Singleton: Implementações Seguras para Threads
- Padrão Factory Method
- Abstract Factory para Famílias de Produtos
- Padrão Builder com API Fluente