quinta-feira, 31 de março de 2016

Padrão Singleton "Double-checked" e Padrão Singleton "Instantâneo"

Padrão Singleton é bastante conhecido e usado como solução para diversas finalidades, onde por questão de controle, segurança e uso da memória desejamos ter apenas uma única instância de uma determinada classe, o que seria o exemplo de uma classe de configurações gerais de um sistema, não poderíamos ter um sistema estável sem garantir que existe apenas uma instancia com essas configurações.

Então abaixo vou mostrar um código de implementação de um singleton “Double-checked” que garante a unicidade da classe mesmo em um ambiente multithread e logo depois vou fazer algumas explicações.

public class MeuSingletonSincronizado{
     
      ... //outros atributos da classe

      private volatile static MeuSingletonSincronizado instance; //uso da palavra reservada volatile
     
      private MeuSingletonSincronizado (){
           
... //algo que preciso ser feito no construtor
     
}
     
      public static MeuSingletonSincronizado getInstance(){
           
            if(instance == null){ //primeira checagem
                 
                  synchronized (MeuSingletonSincronizado.class){
                       
                        if(instance == null){ //segunda checagem
                            
                             instance = new MeuSingletonSincronizado();
                       
                        }
                       
                  }
                 
            }
           
            return instance;
      }
     
      ... //outros métodos da classe

}

Vamos às considerações... Primeiro, o uso do modificador volatile na variável que guarda a instância do nosso singleton faz com que o java sinalize ao processador que este atributo sempre vai ser lido e escrito diretamente da memória principal ignorando o cache, evitando valores diferentes em ambientes multi-threads.


Porque usar a dupla checagem? Quando usamos esse modelo, observe que só sincronizamos a classe no método que retorna a instância enquanto houver a possibilidade de essa instância ser nula, depois disso, não há necessidade dessa sincronização. Isso faz com que ganhemos performance e segurança de que só haverá uma instância da classe.

Já na opção instantâneo, o que muda é que inicializamos a instância do singleton no momento da declaração da variável. O problema é que dependendo do que o seu singleton fizer e da quantidade de classes do tipo singleton que você codificar isso pode trazer um consumo maior de memória, pois o objeto será instanciado no momento que a classe for lida pela JVM mesmo que não venha a ser usada...

public class MeuSingletonSincronizado{
     
      ... //outros atributos da classe

      Private final volatile static MeuSingletonSincronizado instance = new MeuSingletonSincronizado();
     
      private MeuSingletonSincronizado(){}// construtor
     
     
      public static MeuSingletonSincronizado getInstance(){
                 
            return instance;

      }
     
      ... //outros métodos da classe

}

Nenhum comentário:

Postar um comentário