A singleton pattern of design patterns

Source: Internet
Author: User

Singleton mode is a very common and simple design pattern in our development process, and the purpose of using singleton mode is to make one object of the class become the only real

Cases. Take a familiar example----Windows Task Manager, in the Windows taskbar, right-click to select Task Manager, which opens a Task Manager window

(as shown), and then the same operation a few times to see if it is open more than one window or a window, without modifying the Windows kernel, the open is definitely the only

a a window, which means "Task Manager" is a singleton in our Windows operating system, so why is Microsoft designing this? We can score from the following two points

Analysis: First, if you open the two The contents of the Task Manager window are consistent, that is, duplicate objects, The Task Manager gets the real-time state information of the computer to be consumed

a certain system resources, duplicate objects are obviously wasting resources. Second, if the open window shows inconsistent content, then the situation is bad, a window displays

CPU Usage 5%, the other shows CPU utilization 90%, then which is the right one? In conclusion, it is advisable for Microsoft to design the task Manager as a singleton model.



back in software development, sometimes we need to conserve system resources, sometimes in order to ensure that only one instance of the system, all operations can only be based on this instance. In order to ensure the uniqueness of this instance, we need to use a singleton pattern to implement it.

In Task Manager, for example, there are a number of member methods in the Task Manager, I select the display process and service as an example, to briefly introduce the singleton mode.

There are three key points to implementing the Singleton pattern: first, a class can have only one instance; second, it must be able to create an instance on its own; thirdly, it must be able to provide a global access method to the whole system on its own.

One. A hungry man mode:

Package com.moluo.test;   /**    * @author xingzhemoluo    */public class TaskManager {//A hungry man mode   thread safety//instance is instantiated when class is loaded, avoiding multithreading synchronization problems private Static TaskManager instance = new TaskManager ();p rivate TaskManager () {//Perform the initialization operation, must be private because you want to prevent other classes from creating instances in new way} public void Displayservice () {//Display service}public void displayprocess () {//Show process}public static TaskManager getinstance () {retur n Instance;}}
Declare and create a static instance first, and then declare the number of constructed rows as private, because this prevents direct new creation of an instance in other classes. Finally, a global access method is provided, which tells the instance to provide access to the outside world. This instance is instantiated when the class is loaded, it is thread-safe, but does not implement lazy loading, because the instance is created by the JVM itself, but sometimes we do not need this instance, but it is loaded by the JVM, obviously wasting system resources, so we must improve this "a Hungry man mode" To implement lazy loading, so you have the following type of "lazy mode".

Two. Lazy mode:

Package com.moluo.test;/** * @author Xingzhemoluo */public class TaskManager1 {//Lazy mode   thread unsafe private static TaskManager1 instance;private TaskManager1 () {///Perform initialization operation, must be private because you want to prevent other classes from creating instances in new way}public void Displayservice () {//Display service}public void displayprocess () {//Display process}public static TaskManager1 getinstance () {if (instance = = null) {Instanc E = new TaskManager1 ();} return instance;}}
The difference from the first "a Hungry man mode" is that the declaration of instance is not created directly, just declared, and then in the global access method, that is, getinstance () Executes instance = new TaskManager1 () to create an instance. When the system calls this getinstance () method, the instantiation is performed, obviously this "lazy mode" implementation of lazy loading, that is, the use of the load, do not use does not load. But this "lazy pattern" is obviously not thread-safe, because when multiple threads access the GetInstance method at the same time, and all pass the IF statement at the same moment, multiple instances are created. Therefore, this method may cause instances to be not unique when multithreaded concurrent access, so we must add synchronous locks for thread safety.

Three. Improved lazy mode:

Package com.moluo.test;/** * @author Xingzhemoluo */public class TaskManager2 {//Use a sync lock to improve the lazy mode to handle simultaneous access problems for multiple threads.  private static TaskManager2 instance;private TaskManager2 () {//performs the initialization operation and must be private because the other classes are prevented from creating instances in new ways}public void Displayservice () {//Display service}public void displayprocess () {//Show process}public static synchronized TaskManager2 getinstance ( {if (instance = = null) {instance = new TaskManager2 ();} return instance;}}
With the "lazy pattern" above.compared to, this improved"lazy Mode" is simply the signature of the global Access Method getinstance () plus the sync Lock: Synchronized, this improved method is used by the JVM to lock the thread, so the thread is secure, so the created instance is also unique. However, this method has a bad disadvantage: each call to the getinstance () method is a thread lock judgment, so the performance is low, so the method needs to be improved.

Four. Again improved lazy mode:

Package com.moluo.test;/** * @author Xingzhemoluo */public class TaskManager3 {//resolves thread safety issues and deferred loading, but it is possible to generate multiple instances of private Static TaskManager3 instance;private TaskManager3 () {//Perform initialization operation, must be private because you want to prevent other classes from creating an instance with new method}public void Displayservice () {//Display service}public void displayprocess () {//Show process}    //Put synchronized inside to implement lazy loading public static  TaskManager3 getinstance () {if (instance = = null) {synchronized (taskmanager3.class) {instance = new TaskManager3 ();}} return instance;}}
Compared with the above improved "lazy mode", when the global access method creates an instance with a synchronous lock, this method implements lazy loading and the thread is secure, but it is possible to produce multiple instances.

If at some point both thread A and thread B are calling the GetInstance () method, the instance object is a null value, which can be judged by instance = = null. With the implementation of the synchronized lock mechanism, thread A enters the synchronized locked code to execute the instance creation code, thread B is queued and must wait for thread A to complete before it can enter the synchronized lock code. However, when a executes, thread B does not know that the instance has been created, and will continue to create a new instance, resulting in multiple singleton objects.

Five. Double judgment

Package com.moluo.test;/** * @author Xingzhemoluo */public class TaskManager4 {//double lock, but uses a volatile modifier that masks some of the JVM's code optimizations, Code inefficient private static volatile TaskManager4 instance;private TaskManager4 () {//Perform initialization operation, must be private, Because you want to prevent other classes from using new to create instances}public void Displayservice () {//Display service}public void displayprocess () {//Show process}    // Put synchronized inside, and double-judge to implement lazy load public static  TaskManager4 getinstance () {if (instance = = null) {synchronized ( Taskmanager4.class) {//Lock code block if (instance = = null) {instance = new TaskManager4 ();}}} return instance;}}
Compared with the above improvement method, this improved method of knowledge in the lock code block plus a judge whether the null condition, note: Double judgment must be declared instance when the volatile to decorate, so that can correctly handle multi-threading, in order to achieve a singleton. But Vollatile will block some of the code optimizations made by the Java Virtual machine, which is less efficient. So, it needs to be improved.

Six. Static inner class implementation single case

Package com.moluo.test;/** * @author Xingzhemoluo */public class TaskManager5 {    //Add a static (static) inner class to the Singleton class, Create a singleton object in the inner class, and then return the singleton object to the external using private TaskManager5 () {///To perform the initialization operation via the getinstance () method, which must be private because you want to prevent other classes from creating instances in new way} public void Displayservice () {//Display service}public void displayprocess () {//Show process}public static  TaskManager5 getinstance () {return classholder.instance;} Inner class private Static class Classholder {private static TaskManager5 instance = new TaskManager5 ();}}
This method first creates a static inner class Classholder, declares and creates a instance in the static inner class, and then invokes the instance in the global access method to implement a lazy load and implement a singleton. Because the static inner class only actively loads the static inner class when it calls GetInstance (), it implements a lazy load, and the JVM ensures that the instance is initialized only once, without thread locking, so the performance is good. It is obvious that this method is the best one to realize the single case, delay loading and high efficiency.

Summary of single-case patterns
As a kind of design pattern with clear target, simple structure and easy understanding, the single-case pattern is used very frequently in software development and widely used in many application software and frameworks.
1. Key Benefits
The main advantages of the singleton pattern are as follows:
(1) Singleton mode provides controlled access to a unique instance. Because the Singleton class encapsulates its only instance, it can tightly control how and when the customer accesses it.
(2) because there is only one object in the system memory, so the system resources can be saved, for some of the objects need to be created and destroyed frequently the singleton pattern can undoubtedly improve the systemThe performance of the system.
(3) Allow a variable number of instances. Based on the singleton pattern, we can extend this by using a method similar to that of a single control to obtain a specified number of object instances, saving the systemsystem resources, but also solves the problem of single-instance object sharing too much lossy performance.
2. Main disadvantages
The main disadvantages of the singleton pattern are as follows:
(1) Because there is no abstraction layer in the singleton pattern, the expansion of the Singleton class is very difficult.
(2) The duty of the Singleton class is too heavy, which violates the "single duty principle" to a certain extent. Because the Singleton class serves both as a factory role, provides a factory approach, and acts as aProduct roles, including business methods, combine the creation of products with the functionality of the product itself.
(3) Many object-oriented languages (such as Java, C #) are now operating environments that provide automatic garbage collection, so if the instantiated shared object is not exploited for a long time, the system will consider it garbage, automatically destroy and recycle the resources, and re-instantiate the next exploit, which will result in a shared singleton Like the loss of state.
3. Applicable scenarios
You might consider using singleton mode in the following situations:
(1) The system requires only one instance object, such as a system requirement to provide a unique serial number generator or resource manager, or to consider that the resource consumption is too large to allow only one object to be created.
(2) A single instance of the client invocation class allows only one public access point, except for that public access point, which cannot be accessed by other means.


Reference: http://blog.csdn.net/lujiancs/article/details/8278843


Respect copyright, reprint please indicate this article link

Welcome to follow the public number (Xingzhemoluo), common communication programming experience, scan the following QR code can be;








A singleton pattern of design patterns

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.