In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces the relevant knowledge of how to realize the singleton pattern of Java design pattern, the content is detailed and easy to understand, the operation is simple and fast, and it has a certain reference value. I believe you will gain something after reading this article on how to realize the singleton pattern of Java design pattern. Let's take a look.
Singleton mode
The singleton pattern, as its name implies, is a single instance that involves a single class, which is responsible for creating its own object, while ensuring that only one object is created, and provides a way to access the object directly. There is no need to instantiate objects of this class.
Characteristics of the singleton model:
1. A singleton class can have only one instance
two。 This instance must be created by the singleton class itself.
3. The singleton class needs to be provided to the outside world to access this instance.
The role of the singleton model:
The singleton pattern is mainly designed to ensure that there is only one instance of a class in a Java application.
1. The structure of the singleton pattern
The singleton model mainly has the following roles:
Singleton class
A class that can only create one instance
Access class
A test class is a class that uses a singleton class
two。 The realization of singleton pattern 2.1 hungry Han style
Hungry Chinese style: create the single instance class object when the class is loaded
1. Hungry Chinese-mode 1 static member variables
Create a singleton class of hungry Han static member variables
Public class Demo1 {/ * Private constructor makes it impossible for outsiders to create this class object * / private Demo1 () {} / * create this class object static in a class because the external method getInstance () is static * this object instance is a static member variable * / private static Demo1 instance = new Demo1 () / * provides a public access method for outsiders to obtain the object static of this class because the outside world does not need to create an object, but directly accesses * / public static Demo1 getInstance () {return instance;}} through the class.
Create a hungry Chinese static member variable test class (access class)
Public class Test1 {public static void main (String [] args) {/ / create objects of demo1 class cannot be created through new at this time, because the constructor of demo1 is private Demo1 instance = Demo1.getInstance (); Demo1 instance1 = Demo1.getInstance (); / / determine whether two objects are the same System.out.println (instance = = instance1);}}
The output true indicates that it is the same object and points to the same memory address, so we ensure that only one object in the Demo1 singleton class is created
two。 Hungry Chinese style-mode 2 static code block
Create a singleton class of hungry Chinese static code block
Public class Demo2 {/ / static Chinese singleton class static code block / * Private constructor makes it impossible for outsiders to create this kind of object * / private Demo2 () {} / * declare a static member variable instance but not assign a value (no object is created) * No instance is assigned, default is null * / private static Demo2 instance / * assign a value to instance (create an object) in the static code fast * / static {instance = new Demo2 ();} / * provide a public access method so that the outside world can obtain the object static of this class because the outside world does not need to create an object and directly accesses * / public static Demo2 getInstance () {return instance;}} through the class.
Create a hungry Chinese static code block test class
Public class Test2 {public static void main (String [] args) {Demo2 instance = Demo2.getInstance (); Demo2 instance1 = Demo2.getInstance (); System.out.println (instance = = instance1);}}
The output true indicates that it is the same object and points to the same memory address, so we ensure that only one object in the Demo2 singleton class is created
3. Hungry Chinese style-Mode 3 (enumerated)
The enumerated class implementation singleton pattern is a highly recommended singleton implementation pattern, because the enumeration type is thread-safe and will only be loaded once, which is very consistent with the characteristics of the singleton pattern, and the enumeration method is the only singleton implementation pattern that will not be broken.
Singleton class
/ / create singleton public enum Singleton {INSTANCE;} by enumeration
Test class
Public class Test1 {public static void main (String [] args) {Singleton instance = Singleton.INSTANCE; Singleton instance1 = Singleton.INSTANCE; System.out.println (instance = = instance1); / / output true}}
Note:
Because the enumeration method is hungry Han style, according to the characteristics of hungry Han style, enumeration will also cause memory waste, but without considering the memory problem, enumeration is the first choice, after all, it is the easiest to implement.
2.2 lazy style
Lazy: the single instance object is not created when the class is loaded, but only when the object is used for the first time
1. Lazy style-mode 1 (thread unsafe)
Public class Demo3 {/ * Private constructor makes it impossible for outsiders to create this class object * / private Demo3 () {} / * create this class object static in the class because the external method getInstance () is static * no assignment (create object) * / private static Demo3 instance / * provides a public access method for outsiders to obtain the object static of this class because the outside world does not need to create an object, but directly accesses * / public static Demo3 getInstance () {/ / create it when the object is used for the first time, so the instance assignment, that is, object creation is to create instance = new Demo3 () in the method getInstance () that gets the singleton class. Return instance;}} public class Test3 {public static void main (String [] args) {Demo3 instance = Demo3.getInstance (); Demo3 instance1 = Demo3.getInstance (); / / determine whether two objects are the same System.out.println (instance = = instance1);}}
The output is false, indicating that we failed to create a lazy singleton. This is because we new an instance object every time we call getInstance (), so it must not be equal.
/ / if instance is null, indicating that no object of this class has been created, then create if (instance = = null) {instance = new Demo3 ();} / / if instance is not null, it indicates that the object of this class has been created. According to the characteristic that only one object can be created in the singleton class, so / / We directly return instance return instance;}
Note:
We are testing is only single-threaded, but in the practical application must consider the problem of multithreading. Let's suppose that thread 1 enters if judgment and then has no time to create instance, at this time thread 1 loses the execution power of cpu and becomes blocked, thread 2 gets the right to execute cpu, and then determines whether instance is null at this time by if, so thread 2 creates the singleton object for instance assignment, and when thread 1 gets the cpu execution power again, the singleton object is also created by instance assignment, and the singleton mode is destroyed.
two。 Lazy style-Mode 2 (thread safety)
We can ensure that the singleton mode is still valid under multithreading by adding a synchronized synchronization lock.
Public static synchronized Demo3 getInstance () {/ / is created when the object is first used, so the instance assignment, that is, object creation is created in the method getInstance () that gets the singleton class from the outside. / / if instance is null, indicating that no object of this class has been created, then create if (instance = = null) {instance = new Demo3 () } / / if instance is not null, it indicates that the object of this class has been created. According to the characteristic that the singleton class can only create one object, we return instance return instance;} directly.
Note:
Although thread safety issues are guaranteed, the synchronized keyword is added to the getInstance () method, resulting in inefficient execution of the method (a common problem with locking). In fact, we can easily find that we only need to solve the problem of multithreading security when judging instance, but there is no need to lock on getInstance ().
3. Lazy style-Mode 3 (double check lock)
For the getInstance () method, most of the operations are read operations, which are thread-safe, so there is no need for every thread to hold a lock to call the method. We can adjust the timing of the lock.
The public class Demo4 {/ * private constructor makes it impossible for outsiders to create such objects * / private Demo4 () {} / * * without assigning (creating objects) but declaring a variable of this class * / private static Demo4 instance / * provides a public access method for outsiders to obtain the object static of this class because the outside world does not need to create an object. Access directly through the class * / public static Demo4 getInstance () {/ / (judged for the first time) if instance is null, it indicates that no object of this class has been created yet Then create if (instance = = null) {synchronized (Demo4.class) {/ / second judgment if instance is not null if (instance = = null) {instance = new Demo4 () } / / if instance is not null, it indicates that the object of the singleton class has been created, and there is no need to preempt the lock. Return return instance;}} directly.
The double check lock mode perfectly solves the singleton, performance, and thread safety problems, but only this is still a problem.
JVM optimizes and rearranges instructions when creating objects, and null pointer exceptions may occur in multithreading. You can use the volatile keyword, and volatile can ensure visibility and order.
Private static volatile Demo4 instance
If the steps of rearranging instructions 2 and 3 are reversed, the instance points to an empty piece of memory (or possibly a piece of memory with data).
Complete code
The public class Demo4 {/ * private constructor makes it impossible for outsiders to create such objects * / private Demo4 () {} / * volatile guarantees ordering * without assignment (creating objects), it just declares a variable * / private static volatile Demo4 instance of this class. / * provides a public access method for outsiders to obtain the object static of this class because the outside world does not need to create an object. Access directly through the class * / public static Demo4 getInstance () {/ / (judged for the first time) if instance is null, it indicates that no object of this class has been created yet Then create if (instance = = null) {synchronized (Demo4.class) {/ / second judgment if instance is not null if (instance = = null) {instance = new Demo4 () } / / if instance is not null, it indicates that the object of the singleton class has been created, and there is no need to preempt the lock. Return return instance;}} directly.
4. Lazy-4 (static inner class)
In the static inner class singleton mode, the instance is created by the inner class. Because JVM will not load the static inner class in the process of loading the external class, it will only be loaded when the properties / methods of the inner class are called and initialize its static properties. Static properties are guaranteed to be instantiated only once because they are modified by final, and the instantiation order is strictly guaranteed.
Create a singleton class
Public class Singleton {private Singleton () {} / * defines a static inner class * / private static class SingletonHolder {/ / create an object private static final Singleton INSTANCE = new Singleton () in the static inner class;} public static Singleton getInstance () {return SingletonHolder.INSTANCE;}}
Create a test class
Public class Test4 {public static void main (String [] args) {Singleton instance = Singleton.getInstance (); Singleton instance1 = Singleton.getInstance (); / / determine whether two objects are the same System.out.println (instance = = instance1);}}
Note:
INSTANCE is not initialized when the Singleton class is loaded for the first time, only when the getInstance () method is called, JVM loads SingletonHolder and initializes INSTANCE, which ensures thread safety and the uniqueness of the Singleton class.
The static internal class singleton pattern is a commonly used singleton pattern for open source projects, which ensures the security of multithreading without any locking, and without any waste of performance and space.
3. Destruction of singleton pattern
One of the most important features of the singleton pattern is that only one instance object can be created, so if you can enable the singleton class to create more than one, it destroys the singleton pattern (except for enumerations). There are two ways to destroy the singleton pattern:
3.1 serialization and deserialization
Choose one of the above ways to create a singleton pattern (except for enumerations), such as static inner classes
/ / remember to implement the Serializable serialization interface public class Singleton implements Serializable {private Singleton () {} / * define a static inner class * / private static class SingletonHolder {/ / create an object private static final Singleton INSTANCE = new Singleton () in the static inner class;} public static Singleton getInstance () {return SingletonHolder.INSTANCE;}}
Test class
Public class Test1 {public static void main (String [] args) throws IOException {writeObjectToFile ();} / * writes data (objects) to the file * @ throws IOException * / public static void writeObjectToFile () throws IOException {/ / 1. Get the singleton object Singleton instance = Singleton.getInstance (); / / 2. Create an object output stream object ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("d:\\ 1.txt")); / / 3. Write object oos.writeObject (instance); / / 4. Release the resource oos.close ();}}
A file 1.txt appears in the root directory of the d disk because the data is serialized and I can't understand it.
Then we read the instance object from this file
Public static void main (String [] args) throws Exception {/ / writeObjectToFile (); readObjectFromFile (); readObjectFromFile ();} / * read data (objects) from the file * @ throws Exception * / public static void readObjectFromFile () throws Exception {/ / 1. Create object input stream object ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("d:\\ 1.txt")); / / 2. Read object Singleton instance = (Singleton) ois.readObject (); System.out.println (instance); / / 3. Release the resource ois.close ();}
The output results are different, and the conclusion is that serialization destroys the singleton pattern, and the objects of the two reads are different.
Com.xue.demo01.Singleton@2328c243
Com.xue.demo01.Singleton@bebdb06
Solution
Add a readResolve method to singleton
/ * * when deserialization occurs, the method is called automatically, and the returned value of the method is returned directly to * @ return * / public Object readResolve () {return SingletonHolder.INSTANCE;}
Re-write and read, and find that the results of the two reads are the same, which solves the problem of serialization destroying the singleton pattern.
Why can the problem of serialization breaking singletons be solved by adding the readResolve method to the singleton singleton class? in the ObjectInputStream source code, in the readOrdinaryObject method
Private Object readOrdinaryObject (boolean unshared) throws IOException {/ / code snippet Object obj; try {/ / isInstantiable if a class that implements serialization is instantiated at run time, it returns true / / desc.newInstance () creates a new object obj = desc.isInstantiable () by calling the no-parameter construct through reflection? Desc.newInstance (): null;} catch (Exception ex) {throw (IOException) new InvalidClassException (desc.forClass () .getName (), "unable to create instance") .initCause (ex) } / / Code snippet if (obj! = null & & handles.lookupException (passHandle) = null & & / / hasReadResolveMethod returns true desc.hasReadResolveMethod () if the readResolve method is defined in the class implementing the serialization interface) {/ / call the readResolve method of the deserialized class Object rep = desc.invokeReadResolve (obj) by reflection If (unshared & & rep.getClass () .isArray ()) {rep = cloneArray (rep);} / / Code snippet} 3.2 reflection
Choose one of the above ways to create a singleton pattern (except for enumerations), such as static inner classes
Test class
Public class Test1 {public static void main (String [] args) throws Exception {/ / 1. Get the bytecode object Class singletonClass = Singleton.class; / / 2 of Singleton. Get the no-parameter constructor object Constructor cons = singletonClass.getDeclaredConstructor (); / / 3. Cancel access check cons.setAccessible (true); / / 4. Reflection creation object Singleton instance1 = (Singleton) cons.newInstance (); Singleton instance2 = (Singleton) cons.newInstance (); System.out.println (instance1 = = instance2); / / output false indicates that reflection destroys singleton mode}}
Solution:
Public class Singleton {/ / static is so that all can access private static boolean flag = false Private Singleton () {/ / add synchronization lock to prevent multithreading concurrency problem synchronized (Singleton.class) {/ / determine whether flag is true, if it is true, if (flag) {throw new RuntimeException ("cannot create multiple objects") } / / the value of flag is set to true flag = true;}} / * define a static inner class * / private static class SingletonHolder {/ / create an object private static final Singleton INSTANCE = new Singleton () in the static inner class;} public static Singleton getInstance () {return SingletonHolder.INSTANCE }} this is the end of the article on "how to implement the singleton pattern of the Java design pattern". Thank you for reading! I believe you all have a certain understanding of the knowledge of "how to realize the singleton pattern of Java design pattern". If you want to learn more, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.