First, in Java, a single example:
Characteristics:
① Singleton class with only one instance
② Singleton class must create its own unique instance
③ Singleton class must provide this instance to all other objects
Two modes:
① Lazy Singleton < thread unsafe >
When the class is loaded, the instance is not created and is created when the call is run. Class load fast, slow to get objects at run time
Example:
//Lazy Mode Public classPet {PrivatePet () {}Private StaticPet pet=NULL; Public StaticPet GetInfo () {if(pet==NULL) {Pet=NewPet (); } returnPet; }}
② a hungry man-type single < thread safety >
When the class loads, the initialization is complete. So class loading is slow, but getting objects at run time is fast
Example:
// a hungry man mode Public class Pet { private Pet () { } privatestatic pet pet=New Pet (); Public Static Pet GetInfo () { return pet; }}
A Hungry man mode thread safety, however, lazy mode thread security is not high, if multi-threading, how can we guarantee the singleton?
The first method: synchronization
On the method call added synchronization, although the thread is safe, but each time to synchronize, will affect performance, after all, 99% of the case is not required to synchronize
Public Static synchronized Pet GetInfo () { if(pet==null) { Pet=new Pet (); } return pet; }
Second method: Double check lock
Two null checks in GetInfo ensure that only the first invocation of the singleton is synchronized, which is thread-safe and avoids the performance loss of synchronization every time.
The so-called "double check plus lock" mechanism, refers to: not every time into the GetInstance method need to synchronize, but first out of sync, enter the method, first check whether the existence of the instance, if not exist before the following synchronization block, this is the first check, into the synchronization block, again check if the instance exists, If it does not exist, an instance is created in the case of synchronization, which is the second check. In this way, you only need to synchronize once, which reduces the time wasted in the synchronization of multiple judgments.
The implementation of the double check lock mechanism uses the keyword volatile, which means that the value of a volatile variable is not cached by the local thread, and that all read and write to the variable is directly operating shared memory, ensuring that the variable is handled correctly by multiple threads.
Public Static Pet GetInfo () { if(pet==null) { synchronized(pet.class { if(pet==null) { Pet=new Pet (); } } } return pet; }
Third method: Static inner class
The ClassLoader mechanism is used to ensure that only one thread is initialized, so it is thread-safe with no performance loss
Public classPet {Private Static classLazyholder {Private Static FinalPet INSTANCE =NewPet (); } PrivatePet () {} Public Static FinalSingleton GetInfo () {returnlazyholder.instance; } }
Resource Loading and performance:
The A Hungry man mode instantiates a static object at the same time that the class is created, regardless of whether the singleton will be used later, it will take up a certain amount of memory, but correspondingly, it will be very fast at the first call because its resources have already been initialized.
Lazy mode will delay loading, the first time you use the singleton to instantiate the object, the first call to do initialization, if you want to do more work, performance will be some delay, after the same as the A Hungry man mode.
A single example of Java design patterns