English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Análise completa do padrão de design Java Singleton

Este artigo compartilha com vocês o código específico do padrão Singleton do Java Design Patterns, para referência, o conteúdo específico é o seguinte

Conceito:

Padrão Singleton: uma classe possui apenas uma instância.

Um único objeto de uma classe, que oferece um ponto de acesso global.

A razão para usar esse padrão é:

  Quando navegamos em sites, alguns deles mostram 'Número de pessoas online no momento'. Geralmente, a maneira de implementar essa funcionalidade é armazenar cada IP que se conecta em uma memória, arquivo ou banco de dados, e cada novo IP realiza o+1geralmente é implementado por um método, por exemplo, add(), para implementar “}}+1função, por exemplo, usando a instrução 'update', primeiro obtenha os dados armazenados no banco de dados, então+1Atualize os dados no banco de dados, então salve; ao exibir na página, você pode obter os dados do banco de dados através de outro método. Mas, quando vários usuários entram ao mesmo tempo, se cada um criar um objeto, então chamar o método 'add()' através de 'objeto.métodoNome' e armazenar os dados no banco de dados, isso causará que vários usuários não possam registrar os dados do usuário de fato no banco de dados. Portanto, projetar este contador como um objeto global (todos usam este objeto, não um, novo), todos compartilham o mesmo conjunto de dados, isso pode evitar problemas semelhantes, isso é o que chamamos de uma aplicação do padrão Singleton. 

Da mesma forma, também há outras situações onde você encontrará uma situação semelhante, utilizando uma lógica semelhante. Por exemplo:

   1. Recursos externos: Cada computador tem vários impressoras, mas só pode haver um PrinterSpooler para evitar que duas tarefas de impressão sejam enviadas ao impressora ao mesmo tempo. Recursos internos: A maioria dos softwares tem (ou vários) arquivos de propriedades para armazenar configurações do sistema, e esses sistemas devem ter um objeto para gerenciar esses arquivos de propriedades.
   2. O Gerenciador de Tarefas do Windows (Task Manager) é um exemplo muito clássico do padrão Singleton (você está familiarizado com isso, certo?). Pense, você pode abrir dois gerenciadores de tarefas do Windows? Não acredita? Experimente você mesmo!
   3. O Recycle Bin do Windows (lixo eletrônico) é um exemplo clássico de aplicação Singleton. Durante todo o processo de execução do sistema, o lixo eletrônico mantém apenas uma instância.
   4. O contador do site geralmente também é implementado usando o padrão Singleton, de outra forma, é difícil sincronizar.
   5. A aplicação do log da aplicação geralmente também utiliza o padrão Singleton para implementação, geralmente devido ao fato de que o arquivo de log compartilhado está sempre aberto, pois só pode haver uma instância para operar, caso contrário, o conteúdo não pode ser adicionado corretamente.
   6. A leitura do objeto de configuração da aplicação Web geralmente também aplica o padrão Singleton, devido ao fato de que o arquivo de configuração é um recurso compartilhado.
   7. O design do pool de conexões de banco de dados geralmente também utiliza o padrão Singleton, pois a conexão de banco de dados é um tipo de recurso de banco de dados. No sistema de software de banco de dados, o uso do pool de conexões de banco de dados é principalmente para economizar a eficiência de abertura ou fechamento de conexões de banco de dados, que é muito cara, pois ao usar o padrão Singleton para mantê-la, pode-se reduzir significativamente essa perda.
   8. O design do pool de threads em multi-threading geralmente também utiliza o padrão Singleton, devido à necessidade de facilitar o controle das threads no pool.
   9. O sistema de arquivos do sistema operacional, também é um exemplo específico de implementação do padrão Singleton, onde um sistema operacional pode ter apenas um sistema de arquivos.
   10. HttpApplication também é um exemplo típico de singleton. Quem está familiarizado com o ciclo de vida completo da solicitação do ASP.Net (IIS) deve saber que HttpApplication também é um padrão singleton, todos os HttpModule compartilham uma instância de HttpApplication. 

Resumindo, as aplicações gerais do padrão singleton são:

    1. Objetos que precisam ser instanciados e destruídos frequentemente.

    2. Objetos que consomem muito tempo ou recursos ao criar, mas são usados frequentemente.

      3. Objetos de classe de ferramentas com estado.

    4. Objetos que acessam frequentemente o banco de dados ou arquivos.

    5. Evita perdas ou perda de desempenho devido à operação de recursos, como arquivos de log e configurações de aplicativos mencionados acima.

    6. Facilita a comunicação entre recursos sob controle, como pools de threads.

Características:

1、 A classe singleton pode ter apenas uma instância

2、 A classe singleton deve criar sua própria instância única

3、 A classe singleton deve fornecer essa instância para todos os outros objetos

Elementos do padrão singleton: 

   1. Construtor privado
   2. Referência estática privada apontando para sua própria instância
   3. Método público estático que retorna sua própria instância 

Três métodos para implementar o padrão singleton:

1. O padrão Hungry汉: a instância singleton é construída no momento da carga da classe, inicialização aguda (método de pré-carga).

/**
* Hungry汉式(recomendado)
*
*/
public class Test {
    private Test() {
    }
    public static Test instance = new Test();
    public Test getInstance() {
        return instance;
    }
}

Vantagens 

    1. threadsafe
    2. Um objeto estático já foi criado durante a carga da classe, a velocidade de resposta ao chamar é rápida

Desvantagens 

    A eficiência dos recursos não é alta, pode ser que getInstance() nunca seja executado, mas ao executar outros métodos estáticos dessa classe ou carregar a classe (class.forName), ainda assim, a instância ainda será inicializada

2. O padrão lazy汉: a instância singleton é construída pela primeira vez quando usada, inicialização atrasada.

class Test {
    private Test() {
    }
    public static Test instance = null;
    public static Test getInstance() {
        if (instance == null) {
       //Quando várias threads julgam que instance é null, ao executar a operação new, ocorre uma situação de repetição em múltiplas threads
            instance = new Singleton2()
        }
        return instance;
    }
}

Vantagens 

    Evita o padrão de hambúrguer sem usar, economizando recursos e não sendo instanciado ao executar getInstance(), pode executar outros métodos estáticos dessa classe.

Desvantagens 

    O padrão lazy汉在 uma única thread não há problema, mas quando várias threads acessam ao mesmo tempo, pode criar várias instâncias ao mesmo tempo, e essas várias instâncias não são o mesmo objeto, embora as instâncias criadas posteriormente possam substituir as instâncias criadas anteriormente, ainda assim, ainda pode haver a situação de obter diferentes objetos. A maneira de resolver esse problema é adicionar lock synchronized, a primeira carga não é rápida o suficiente, e o custo de sincronização não necessário em múltiplas threads é grande.

3.duplo teste

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

Vantagens 

    Alta eficiência de uso de recursos, não instanciou, não pode executar o método getInstance() da classe, pode executar outros métodos estáticos da classe

Desvantagens 

    A resposta não é rápida na primeira carga, devido a alguns motivos do modelo de memória do Java, falha ocasionalmente

4.classe interna estática

class Test {
    private Test() {
    }
    private static class SingletonHelp {
        static Test instance = new Test();
    }
    public static Test getInstance() {
        return SingletonHelp.instance;
    }
}

Vantagens 

    Alta eficiência de uso de recursos, não instanciou, não pode executar o método estático getInstance() da classe, pode executar outros métodos estáticos da classe

Desvantagens 

    A resposta não é rápida na primeira carga

Resumo: 

    Geralmente, é usado o estilo greedy, se você se importar muito com recursos, pode usar a classe interna estática, não é recomendado usar o estilo lazy e双重检测 (double-checked locking)

 Isso é tudo o que há no artigo. Espero que ajude no seu aprendizado e que você apoie e incentive o tutorial Grito.

Declaração: O conteúdo deste artigo é extraído da Internet, pertencente ao autor original. O conteúdo é contribuído e carregado voluntariamente pelos usuários da Internet. Este site não possui direitos de propriedade, não foi editado artificialmente e não assume responsabilidade por eventuais responsabilidades legais. Se você encontrar conteúdo suspeito de violação de direitos autorais, seja bem-vindo a enviar e-mail para: notice#oldtoolbag.com (ao enviar e-mail, substitua # por @ para denunciar e forneça provas relevantes. Apenas após verificação, o site deletará o conteúdo suspeito de infringência de direitos autorais.

Você também pode gostar