Implémentation du mode Singleton (5 types)
Couramment utilisé:
Style affamé (filetage sûr, efficacité élevée des appels, mais ne peut pas être chargée de manière retardée)
Style paresseux (Filet Safe, Low Call Efficacité, peut être chargé en retard)
autre:
Type de verrouillage à double détection (en raison du modèle interne sous-jacent de JVM, il y aura des problèmes occasionnellement et ne sera pas construit et utilisé)
Classe interne statique (file d'efficacité en file d'appel, mais peut être chargée de manière retardée)
Énumérer les singletons (filetage, une efficacité élevée des appels et ne peut pas être chargé en retard)
Le code spécifique du singleton de Hungry Man est le suivant:
package com.lcx.mode; / ** * * Un singleton de gens affamés. Peu importe que cet objet soit utilisé à l'avenir ou non, nous créons une instance de cet objet depuis le début. * En cas de besoin, nous renvoyons l'objet d'instance créé, nous avons donc relativement faim, donc cela s'appelle un singleton de personnes affamées. * @Author QQ1013985957 * * / Classe publique SingletonHanger {Instance singletonhanger finale statique privée = new singletonhanger (); privé singletonhanger () {} public static singletonhanger getInstance () {return instance; }} / ** * Singleton de style Lazy Han, lorsqu'un objet Singleton est nécessaire, il créera le seul objet Singleton, et l'appellera à nouveau plus tard, et l'objet Singleton retourné est également le premier objet Singleton créé * Initialise le membre statique à Null, et le crée lorsqu'un singleton est obtenu, donc il est appelé Lazy Han-Style. * @author qq1013985957 * * / class singletonlazy {private static singletonlazy instance = null; privé singletonlazy () {} / ** * Le singleton implémenté par cette méthode ne peut pas être utilisé dans plusieurs threads. Plusieurs lignes peuvent saisir la méthode IF en même temps, ce qui entraînera la génération de plusieurs objets singleton. * @return * / public static singletonlazy getInstance1 () {if (instance == null) {instance = new singletonlazy (); } return instance; } / ** * Tout le monde pensera à la synchronisation. La méthode synchrone peut implémenter un singleton multi-thread * Cependant, cette méthode n'est pas souhaitable et affecte sérieusement les performances. Parce que la méthode doit être vérifiée chaque fois que vous obtenez un singleton, vous ne pouvez utiliser le bloc de code synchronisé que pour obtenir une synchronisation. * @return * / public static synchronisé singletonlazy getInstance2 () {if (instance == null) {instance = new singletonlazy (); } return instance; } / ** * Utilisez le bloc de code synchronisé pour utiliser le bloc de code synchronisé dans la méthode IF pour déterminer si un singleton existe et vérifiez à nouveau dans le bloc de code synchronisé si le singleton a été généré. * Ceci est la méthode de la double vérification du verrouillage sur Internet * @return * / public static synchronisé singletonlazy getInstance3 () {if (instance == null) {synchronisé (singletonlazy.class) {if (instance == null) {instance = new Singletonlazy (); }}} Instance de retour; }} / ** * Utilisez des énumérations pour implémenter le mode Singleton, qui est également le moyen recommandé d'utiliser dans l'instanciation Java * efficace en fonction de la situation spécifique. Pour les étudiants qui ne connaissent pas les énumérations, vous pouvez vous référer à la compréhension préliminaire de mon blog Java Enumeration Class. * Ses avantages: il est plus concis et fournit un mécanisme de sérialisation gratuitement, empêchant absolument plusieurs instanciations, même face à des attaques complexes de séquence et de réflexion. * @Author QQ1013985957 * * / Enum SingleterionEnum {SingleterionEnum ("Singleton Enum"); String privé Str; privé singleteitionNum (string str) {this.setstr (str); } public String gettr () {return str; } public void setstr (string str) {this.str = str; }} Le motif de singleton ci-dessus n'est pas testé. Vous pouvez le tester pour déterminer si le code de hash de l'objet est cohérent pour déterminer s'il s'agit du même objet.
Les méthodes maléfiques et paresseuses ne peuvent pas empêcher la réflexion d'implémenter plusieurs instances. Grâce à la réflexion, la définition de la méthode accessible.setaccessible peut appeler le constructeur privé. Vous pouvez modifier le constructeur pour lancer une exception lorsqu'on lui demande de créer une deuxième instance.
En fait, cela ne peut garantir un singleton. Après la sérialisation, la désérialisation peut créer une nouvelle instance et ajouter la méthode ReadResolve () à la classe singleton pour l'empêcher.
Le code singleton de style homme paresseux est le suivant:
package com.lcx.mode; Importer java.io.file; import java.io.fileInputStream; Importer java.io.fileOutputStream; import java.io.objectInputStream; Importer java.io.ObjectOutputStream; import java.io.serializable; import java.lang.reflect.constructor; import java.lang.reflect.invocationtargetException; / ** * Les singletons de style homme paresseux sont créés lorsqu'un objet singleton est nécessaire. Lorsqu'un objet Singleton est nécessaire, il sera rappelé plus tard. L'objet Singleton renvoyé est également le premier objet Singleton créé * initialise le membre statique à Null et le crée lorsqu'un singleton est obtenu, il est donc appelé style homme paresseux. * @Author QQ1013985957 * * / Classe publique Singleton implémente Serializable {/ ** * * / private statique final SerialVersionUID = -5271537207137321645l; Instance singleton statique privée = null; Int statique privé I = 1; Singleton privé () {/ ** * Empêchez les attaques de réflexion, exécutez et appelez le constructeur une fois, lancez l'exception la deuxième fois * / if (i == 1) {i ++; } else {Throw New RuntimeException ("Le constructeur ne peut être appelé qu'une seule fois"); } System.out.println ("Appelez le constructeur privé de Singleton"); } / ** * Utilisez le bloc de code synchronisé pour utiliser le bloc de code synchronisé dans la méthode IF pour déterminer si un singleton existe et vérifiez à nouveau dans le bloc de code synchronisé si le singleton a été généré. * C'est ce que l'Internet appelle la méthode de verrouillage à double vérification * @return * / public static synchronisé singleton getInstance () {if (instance == null) {synchronisé (singleton.class) {if (instance == null) {instance = new singleton (); }} return instance; } / ** * Empêcher la désequence de générer de nouveaux objets singleton. C'est ce qui est dit dans le livre Efficace Java. Cette méthode peut être empêchée. Je ne comprends pas les détails spécifiques * @return * / objet privé ReadResolve () {return instance; } public static void main (String [] args) lève une exception {test1 (); test2 (); } / ** * Tester la désequence est toujours le mode singleton * @throws exception * / public static void test2 () lève une exception {singleton s = singleton.getInstance (); ObjectOutputStream ObjectOutputStream = new ObjectOutputStream (new FileOutputStream (nouveau fichier ("e: //singleton.txt"))); objectOutputStream.WriteObject (S); ObjectInputStream objectInputStream = new ObjectInputStream (new FileInputStream (nouveau fichier ("e: //singleton.txt")))); Objet 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 (); } / ** * Test Reflection Attack * @throws Exception * / public static void test1 () {singleton s = singleton.getInstance (); Classe C = singleton.class; Constructeur du constructeur; essayez {privateConstructor = c.getDeclaredConstructor (); privateconstructor.setAccessible (true); privateconstructor.newinstance (); } catch (exception e) {e.printStackTrace (); }}}Vérifiez les résultats de l'attaque de réflexion:
Si le résultat de la méthode ReadResolve n'est pas ajouté:
Le résultat de l'ajout de la méthode ReadResolve:
Merci d'avoir lu, j'espère que cela peut vous aider. Merci pour votre soutien à ce site!