Padrão Criacional: Singleton
Este artigo discute como o padrão Singleton obriga apenas uma única instância de uma classe a ser produzida e existir durante o tempo de vida de um aplicativo.

O que é isso?
Um singleton é um padrão de design usado para criar a única instância de classe. O padrão Singleton é normalmente usado quando há vários exemplos em que apenas uma única instância de uma classe deve existir e a restrição deve ser aplicada. Por exemplo, caches, pools de encadeamentos e registros devem ter apenas uma instância.
Torne o construtor privado para garantir que apenas um objeto de classe seja criado. Dessa forma, apenas os membros da classe podem acessar o construtor privado e mais ninguém.
No mundo real, o padrão Singleton garante que exista apenas uma única instância de classe e oferece um ponto global de acesso a ela.
Diagrama de classe
O diagrama de classes contém apenas uma entidade.
solteiro

Exemplo
Digamos que queremos modelar a aeronave oficial do presidente americano chamada Airforce One em nosso software. A classe Singleton é a representação mais adequada para uma entidade com apenas uma instância.
Aqui está o código para nossa classe singleton:

Multithreading e Singleton
Esse código funciona desde que o aplicativo seja de thread único. No entanto, se vários threads acessarem essa classe, existe a possibilidade de vários objetos serem criados.
Por exemplo:
- A thread A chama o método
getInstance
e descobre que oonlyInstance
é nulo; no entanto, antes que ele possa criar uma instância, ele é trocado de contexto. - Agora o thread B vem e chama
getInstance
, que retorna oAirforceOne
objeto. - Se o thread A for agendado novamente, o dano começa. O thread já passou pela verificação de condição if-null e continuará criando um novo
AirforceOne
objeto e atribuindo-o aonlyInstance
. Agora existem doisAirforceOne
objetos diferentes na natureza, um com thread A e outro com thread B.
- Ao adicionar
synchronized
aogetInstance()
método, você pode obter a segurança do encadeamento. - Outra opção é inicializar a instância estaticamente, garantindo que ela seja thread-safe.


Bloqueio duplamente verificado
Existem dois problemas significativos com as abordagens descritas acima: a sincronização é cara e a inicialização estática cria o objeto mesmo que ele não seja usado em uma determinada execução de aplicativo. Se a criação do objeto for cara, a inicialização estática pode nos custar desempenho.

A solução acima marca a instância singleton volátil. No entanto, essa implementação da volatile
metodologia da JVM não funcionará corretamente para o bloqueio verificado duas vezes e você precisará de outra abordagem para criar seus singletons.
O idioma de bloqueio verificado duas vezes agora é considerado um antipadrão, e seu utilitário acabou principalmente porque os tempos de inicialização da JVM aceleraram.
Outros exemplos
A API Java nos fornece os seguintes singletons:
java.lang.Runtime
java.awt.Desktop
Ressalvas
Você pode criar uma subclasse de uma classe singleton protegendo o construtor em vez de private. No entanto, existem escolhas melhores do que isso em todas as circunstâncias. Nessas situações, os desenvolvedores podem criar um registro de singletons para todas as subclasses. O método getInstance pode receber um parâmetro ou usar uma variável de ambiente para retornar o objeto singleton desejado. O registro mantém um mapeamento de nomes de string para objetos singleton.