The singleton model is the simplest design model among the 23 design models, and it is also widely used in enterprise development. The advantage of singleton pattern is that there is only one instance in the project.
Features: The constructor is privatized, the object is privatized, and only provides an external access interface.
Application scenarios:
1. The system needs to share resources: such as log system, spring resource manager, etc.
2. In order to control the use of resources: such as thread pool
Common applications in enterprise-level development and common frameworks:
servlets in J2EE, resource managers in Spring (i.e. beans), database connection pools, thread pools, log systems, website counters, etc.
Singleton pattern classification:
1. Hungry mode: Hungry mode is the simplest singleton mode for code, but the instance is loaded when the class is initialized. If it is not used instantly, the system loading speed will be slowed down. The specific code is as follows:
public class Singleton{ private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; }}2. Lazy mode: Compared with Hungry mode, the lazy mode is instantiated and placed in the only external interface to process, which realizes delayed loading, saving system initialization time, but there is a situation where threads are unsafe.
public class Singleton{ private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ return new Singleton(); } return instance; }}3. Double check lock: The double check lock mode is actually an upgrade of the lazy mode, making the lazy mode thread-safe. Note: There is a memory problem with the double check lock, which may invalidate the double check lock.
public class Singleton{ private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ synchronized(Singleton.class){ if(instance == null){ return new Singleton(); } } return instance; }}4. Static internal class mode: The static internal class has both lazy and evil modes: thread-safe, delayed loading.
public class Singleton{ private static class SingletonFactory{ private static Singleton INSTANCE = new Singleton(); } private Singleton(){} public static Singleton getInstance(){ return SingletonFactory.INSTANCE; }}5. Enumeration class mode: It should be the most perfect single-interest mode, which is not only thread-safe, but also prevents desequence and reflection problems.
enum Singleton{ INSTANCE; public void doSomething(){ ... }}Singleton pattern details issue:
1. Reflection breaks the singleton mode: reflection can destroy the implementation of the singleton mode (except for enumeration mode)
/** *Destroy singleton mode by reflection*/public class Demo01 { public static void main(String[] args) throws Exception { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1 == s2); Class<Singleton> clazz = (Class<Singleton>) Class.forName("com.singleton.Singleton"); Constructor<Singleton> constructor = clazz.getDeclaredConstructor(null); constructor.setAccessible(true); Singleton s3 = constructor.newInstance(); System.out.println(s1 == s3); }}class Singleton{ private static Singleton instance = new Singleton(); private Singleton(){ // Method to prevent reflection from destroying the single-interest mode, open the comment section// if(instance != null){// throw new RuntimeException();// } } public static Singleton getInstance(){ return instance; }}In fact, the so-called prevention means making it impossible to create through reflection.
2. Deserialization breaks the singleton pattern (except for enumeration class pattern)
/** * Deserialization breaks the singleton pattern*/public class Demo02 { public static void main(String[] args) throws Exception { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1 == s2); FileOutputStream fos = new FileOutputStream("d://test.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(s1); oos.close(); fos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d://test.txt")); Singleton s3 = (Singleton) ois.readObject(); System.out.println(s1 == s3); }}class Singleton implements Serializable{ private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } //Default deserialization, if the object already exists, this method will be called// private Object readResolve() throws ObjectStreamException{// return instance;// // }}These two situations are limited to understanding and are not used much in the actual development process.
At this point, the singleton pattern is complete.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.