Implementação do modo singleton (5 tipos)
Comumente usado:
Estilo faminto (fios seguros, alta eficiência de chamada, mas não pode ser carregada de maneira atrasada)
Estilo preguiçoso (fios seguros, baixa eficiência de chamada, pode ser carregada em atraso)
outro:
Tipo de bloqueio de detecção dupla (devido ao modelo interno subjacente da JVM, haverá problemas ocasionalmente e não será construído e usado)
Classe interna estática (segura por rosca, alta eficiência de chamada, mas pode ser carregada de maneira atrasada)
Enumere singletons (segura por fio, alta eficiência de chamada e não pode ser carregada em atraso)
O código específico do Singleton of Hungry Man é o seguinte:
pacote com.lcx.mode; /** * * Um singleton de pessoas famintas. Independentemente de esse objeto ser usado no futuro ou não, criamos uma instância desse objeto desde o início. * Quando necessário, devolvemos o objeto de instância criado, por isso estamos relativamente com fome, para que isso seja chamado de singleton de pessoas famintas. * @author qq1013985957 * */ public class singletonhanger {private estático final singletonhanger instância = new singletonhanger (); private singletonhanger () {} public static singleTonhanger getInstance () {retorna instância; }} /*** Singleton preguiçoso no estilo Han, quando um objeto Singleton for necessário, ele criará o único objeto Singleton e chamá-lo novamente mais tarde, e o objeto Singleton devolvido também é o primeiro objeto criado para singleton* inicializa o membro estático para NULL e o cria quando um singleton é obtido, assim é chamado Lazy Hanyle. * @author qq1013985957 * */ classe singletonlazy {private static singletonlazy instância = null; private singletonlazy () {} /*** O singleton implementado por esse método não pode ser usado em vários threads. Várias linhas podem entrar no método IF ao mesmo tempo, o que fará com que vários objetos singleton sejam gerados. * @return */ public static singletonlazy getInstance1 () {if (instance == null) {instance = new singletonlazy (); } Instância de retorno; } /*** Todos pensam em sincronização. O método síncrono pode implementar singleton multi-thread*, no entanto, esse método não é desejável e afeta seriamente o desempenho. Como o método deve ser verificado toda vez que você recebe um singleton, você pode usar apenas o bloco de código sincronizado para obter sincronização. * @return */ public static sincronizado singletonlazy getInstance2 () {if (instance == null) {instance = new singletonlazy (); } Instância de retorno; } /*** Use o bloco de código sincronizado para usar o bloco de código sincronizado no método IF para determinar se existe um singleton e verifique novamente no bloco de código sincronizado se o singleton foi gerado. * Este é o método de verificação dupla de bloqueio na Internet * @return */ public static sincronizado singletonlazy getInstance3 () {if (instance == null) {synchronized (singletonlazy.class) {if (instance == null) {instance = new singletonlazazy (); }}} retornar a instância; }} /*** Use as enumerações para implementar o modo singleton, que também é a maneira recomendada de usar na instanciação eficaz de Java* de acordo com a situação específica. Para os alunos que não estão familiarizados com as enums, você pode se referir ao entendimento preliminar da aula de enumeração Java do meu blog. * Seus benefícios: é mais conciso e fornece um mecanismo de serialização para livre, impedindo absolutamente a instanciação múltipla, mesmo diante de sequência complexa e ataques de reflexão. * @author qq1013985957 * */ enum singleTionenum {singleToionenum ("singleton enum"); Private String Str; private singleTioneNum (string str) {this.SetStr (str); } public string getttr () {return str; } public void setStr (String str) {this.str = str; }} O padrão de singleton acima não é testado. Você pode testá -lo para determinar se o código de hash do objeto é consistente para determinar se é o mesmo objeto.
Os métodos malignos e preguiçosos não podem impedir a reflexão de implementar várias instâncias. Através da reflexão, definir o método acessível.SetAccessible pode chamar o construtor privado. Você pode modificar o construtor para lançar uma exceção quando ele é solicitado a criar uma segunda instância.
De fato, isso não pode garantir um singleton. Após a serialização, a desserialização pode criar uma nova instância e adicionar o método readResolve () à classe Singleton para evitá -la.
O código singleton preguiçoso ao estilo homem é o seguinte:
pacote com.lcx.mode; importar java.io.file; importar java.io.fileInputStream; importar java.io.fileOutputStream; importar java.io.ObjectInputStream; importar java.io.ObjectOutputStream; importar java.io.serializable; importar java.lang.reflect.Constructor; importar java.lang.reflect.invocationTargeTexception; /*** Singletons preguiçosos no estilo homem são criados quando um objeto Singleton é necessário. Quando um objeto Singleton for necessário, ele será chamado novamente mais tarde. O objeto Singleton devolvido também é o primeiro objeto Singleton criado* inicializa o membro estático a NULL e o cria quando um singleton é obtido, por isso é chamado de homem preguiçoso. * @author qq1013985957 * */ classe pública Singleton implementa serializável {/ ** * */ private estático final serialversionuid = -5271537207137321645l; Instância de singleton estática privada = nulo; estático privado int i = 1; Private Singleton () { / *** Evite ataques de reflexão, execute apenas e ligue para o construtor uma vez, jogue a exceção na segunda vez* / if (i == 1) {i ++; } else {lança a nova RunTimeException ("o construtor só pode ser chamado uma vez"); } System.out.println ("Call Singleton's Private Constructor"); } /*** Use o bloco de código sincronizado para usar o bloco de código sincronizado no método IF para determinar se existe um singleton e verifique novamente no bloco de código sincronizado se o singleton foi gerado. * É isso que a Internet chama de método de travamento de verificação dupla * @return */ public static sincronizado singleton getInstance () {if (instance == null) {synchronized (singleton.class) {if (instance == null) {instance = new singleton (); }} retornar a instância; } /*** Evite a desamificação de gerar novos objetos singleton. É o que é dito no livro eficaz Java. Este método pode ser evitado. Não entendo os detalhes específicos * @return */ private objeto readResolve () {retorna instância; } public static void main (string [] args) lança Exceção {test1 (); test2 (); } / *** O teste de desigualdade ainda é o modo singleton* @throws Exception* / public static void test2 () lança exceção {singleton s = singleton.getInstance (); ObjectOutputStream ObjectOutputStream = new ObjectOutputStream (new FileOutputStream (new File ("e: //singleton.txt"))); objectOutputStream.WriteObject (s); ObjectInputStream ObjectInputStream = new ObjectInputStream (new FileInputStream (new File ("e: //singleton.txt")))); Objeto readObject = objectInputStream.readObject (); Singleton S1 = (Singleton) ReadObject; System.out.println ("s.hashcode ():"+s.hashcode ()+", s1.hashcode ():"+s1.hashcode ()); objectOutputStream.flush (); objectOutputStream.close (); objectInputStream.close (); objectInputStream.close (); } /** Classe C = Singleton.class; Construtor PrivateConstructor; tente {privateconstructor = c.getDecLaredConstructor (); privateconstructor.setAccessible (true); privateconstructor.newInstance (); } catch (Exceção e) {e.printStackTrace (); }}}Verifique os resultados do ataque de reflexão:
Se o resultado do método readResolve não for adicionado:
O resultado da adição do método readResolve:
Obrigado pela leitura, espero que isso possa ajudá -lo. Obrigado pelo seu apoio a este site!