Java Singleton vs estático - existe um benefício real de desempenho?
-
09-06-2019 - |
Pergunta
Estou mesclando uma ramificação CVS e uma das maiores mudanças é a substituição, sempre que ocorrer, de um padrão Singleton por classes abstratas que possuem um bloco de inicialização estático e todos os métodos estáticos.
Vale a pena manter isso, já que exigirá a fusão de muitos conflitos. Que tipo de situação eu consideraria para que essa refatoração valesse a pena?
Estamos executando este aplicativo no Weblogic 8.1 (portanto, JDK 1.4.2)
desculpe Thomas, deixe-me esclarecer ..
a versão HEAD possui o padrão singleton tradicional (construtor privado, getInstance() etc)
a versão da ramificação não tem construtor, é uma 'classe abstrata pública' e modificou todos os métodos no objeto para serem 'estáticos'.O código que existia no construtor privado é movido para um bloco estático.
Em seguida, todos os usos da classe são alterados, o que causa vários conflitos na mesclagem.
Existem alguns casos em que essa alteração foi feita.
Solução
Do ponto de vista estrito do desempenho do tempo de execução, a diferença é realmente insignificante.A principal diferença entre os dois reside no fato de que o ciclo de vida "estático" está vinculado ao carregador de classe, enquanto para o singleton é um ciclo de vida de instância regular.Normalmente é melhor ficar longe do negócio do ClassLoader, você evita alguns problemas complicados, especialmente ao tentar recarregar o aplicativo da web.
Outras dicas
Eu usaria um singleton se fosse necessário armazenar qualquer estado e, caso contrário, classes estáticas.Não faz sentido instanciar algo, mesmo que seja uma única instância, a menos que seja necessário armazenar algo.
A estática é ruim para a extensibilidade, pois os métodos e campos estáticos não podem ser estendidos ou substituídos por subclasses.
Também é ruim para testes unitários.Dentro de um teste de unidade, você não pode evitar que os efeitos colaterais de diferentes testes se espalhem, pois você não pode controlar o carregador de classe.Os campos estáticos inicializados em um teste de unidade serão visíveis em outro, ou pior, a execução simultânea de testes produzirá resultados imprevisíveis.
Singleton geralmente é um padrão aceitável quando usado com moderação.Prefiro usar uma estrutura de DI e deixar que ela gerencie minhas instâncias para mim (possivelmente em escopos diferentes, como no Guice).
Se minha postagem original tiver o entendimento correto e a discussão da Sun vinculada for precisa (o que acho que pode ser), então acho que você terá que fazer uma troca entre clareza e desempenho.
Faça a si mesmo estas perguntas:
- O objeto Singleton deixa mais claro o que estou fazendo?
- Preciso de um objeto para realizar esta tarefa ou ele é mais adequado para métodos estáticos?
- Preciso do desempenho que posso obter ao não usar um Singleton?
Pela minha experiência, a única coisa que importa é qual deles é mais fácil de zombar em testes unitários.Sempre achei que Singleton é mais fácil e natural de zombar.Se a sua organização permite que você use o JMockit, não importa, pois você pode superar essas preocupações.
Essa discussão ajuda?(Não sei se é tabu vincular a outro fórum de programação, mas prefiro não apenas citar toda a discussão =))
Discussão da Sun sobre este assunto
O veredicto parece ser que isso não faz diferença suficiente na maioria dos casos, embora tecnicamente os métodos estáticos sejam mais eficientes.
Escreva algum código para medir o desempenho.A resposta dependerá da JVM (o JDK da Sun pode ter um desempenho diferente do JRockit) e dos sinalizadores de VM que seu aplicativo usa.