Do an interview today: please introduce the singleton mode

Source: Internet
Author: User
Tags static class volatile

7 ways to style a single case

Reprint Please specify source: http://cantellow.iteye.com/blog/838473



the first type (lazy, thread insecure):

Java code public class Singleton {private static Singleton instance;  Private Singleton () {} public static Singleton getinstance () {if (instance = = null) {instance =       New Singleton ();       } return instance; }   }

public class Singleton {    private static Singleton instance;    Private Singleton () {} public    static Singleton getinstance () {	if (instance = = null) {	    instance = new Singleto n ();	}	return instance;}    }

This type of lazy loading is obvious, but the fatal is that the multithreading does not work properly.

the second type (lazy, thread safe):

Java code public class Singleton {private static Singleton instance;           Private Singleton () {} public static synchronized Singleton getinstance () {if (instance = = null) {       Instance = new Singleton ();       } return instance; }   }

public class Singleton {    private static Singleton instance;    Private Singleton () {} public    static synchronized Singleton getinstance () {	if (instance = = null) {	    instance = New Singleton ();	}	return instance;}    }

This notation works well in multi-threading, and it seems to have a good lazy loading, but, unfortunately, is inefficient and does not require synchronization in 99% cases.

The third type (a Hungry man):

Java code public class Singleton {private static Singleton instance = new Singleton ();       Private Singleton () {} public static Singleton getinstance () {return instance; }   }

public class Singleton {    private static Singleton instance = new Singleton ();    Private Singleton () {} public    static Singleton getinstance () {	return instance;    }}

This approach avoids multi-threaded synchronization problems based on the Classloder mechanism, however, instance is instantiated at class loading, although there are many reasons for class loading, most of which are called getinstance methods in singleton mode. However, it is not certain that there are other ways (or other static methods) that cause the class to load, when initializing instance obviously does not achieve the effect of lazy loading.

the fourth type ( hungry Han, variant):

Java code public class Singleton {private Singleton instance = null;       static {instance = new Singleton ();       } private Singleton () {} public static Singleton getinstance () {return this.instance; }   }

public class Singleton {    private Singleton instance = null;    static {	instance = new Singleton ();    }    Private Singleton () {} public    static Singleton getinstance () {	return this.instance;    }}

The surface looks very different, in fact, the third Way is similar, all in class initialization is instantiated instance.

The fifth type (Static inner Class):

Java code public class Singleton {private static class Singletonholder {private static final Singleton Instan       CE = new Singleton ();       } private Singleton () {} public static final Singleton getinstance () {return singletonholder.instance; }   }

public class Singleton {    private static class Singletonholder {	private static final Singleton INSTANCE = new Sing Leton ();    }    Private Singleton () {} public    static final Singleton getinstance () {	return singletonholder.instance;    }}

This approach also takes advantage of the classloder mechanism to ensure that there is only one thread initialized instance, which differs from the third and fourth ways (very subtle differences): The third and fourth ways are as long as the Singleton class is loaded, Then instance will be instantiated (without the lazy loading effect), and this is singleton class is loaded, instance not necessarily initialized. Because the Singletonholder class is not actively used, the load Singletonholder class is displayed only if it is displayed by calling the GetInstance method, thus instantiating the instance. Imagine if instantiating instance is draining resources, I want him to delay loading, on the other hand, I don't want to instantiate when the singleton class loads, because I can't make sure that the Singleton class can be actively used in other places to be loaded, It is obviously inappropriate to instantiate instance at this time. At this point, this approach is reasonable compared to the third and fourth approaches.

The sixth type (enumeration):

Java code public enum Singleton {INSTANCE; public void Whatevermethod () {}}

public enum Singleton {    INSTANCE;    public void Whatevermethod () {    }}

This approach is advocated by effective Java author Josh Bloch, which not only avoids multi-threaded synchronization problems, but also prevents deserialization from recreating new objects, which can be a very strong barrier, but Personally think that because of the 1.5 to join the enum characteristics, in this way to write inevitably people feel unfamiliar, in the actual work, I also rarely see someone write so.

Seventh type (double check lock): Java code   public class singleton {       private volatile  static Singleton singleton;       private Singleton  () { }       public static singleton getsingleton ()  {       if  (singleton == null)  {            synchronized  (singleton.class)  {            if  (singleton == null)  {                singleton = new singleton ();            }           }        }       return singleton;       }& nbsp; }  

public class Singleton {    private volatile static Singleton Singleton;    Private Singleton () {} public    static Singleton Getsingleton () {	if (Singleton = = null) {	    synchronized (single Ton.class) {		if (singleton = = null) {		    singleton = new Singleton ();}}	}	return singleton;}    }

In simple terms, this is done for performance. This question can be understood in this way. In simple terms, this is done for performance. This question can be understood in this way.

This is the second way of the upgrade version, commonly known as double check Lock, detailed information please see: http://www.ibm.com/developerworks/cn/java/j-dcl.html

After JDK1.5, the double-check lock is able to achieve a single-case effect normally.


This is done for performance. Suppose we remove the first null judgment, because the synchronzied block in the GetInstance method still makes a null judgment, so it is still guaranteed that a class only creates one instance. However, this code makes it possible for syncrhonized blocks to be executed, which means that each thread must obtain an internal lock when executing the GetInstance method, and the cost of acquiring and releasing the lock
(including context switches, memory synchronization, and so on) are unconditionally present. Conversely, if you make a null judgment before executing the syncrhonized block, the probability of the synchronized block being executed by multiple threads is greatly reduced, so that the cost of the lock is maximized. Note: In the case of double checks, the static variable that holds the unique instance must be modified with a volatile modifier. Otherwise, because of a thread-safety reason, a class may still have more than one instance created.

Summary

There are two issues to note:

1. If a singleton is loaded by a different class loader, there may be instances of multiple singleton classes. It is assumed that not remote access, such as some servlet containers, use a completely different class loader for each servlet, so that if there are two Servlets accessing a singleton class, they will have their own instance.

2. If the singleton implements the Java.io.Serializable interface, then instances of this class may be serialized and restored. In any case, if you serialize an object of a singleton class and then restore multiple objects, you will have multiple instances of the Singleton class.

The fix for the first problem is:

  Java code   private static class getclass (string classname)                                                    throws ClassNotFoundException {             classloader classloader = thread.currentthread (). Getcontextclassloader ();                    if (classloader == null)                 classloader = singleton.class.getclassloader ();                    return  ( Classloader.loadclass (classname)); &NBsp;        }     }  

private static Class GetClass (String classname)                                             throws classnotfoundexception {         ClassLoader ClassLoader = Thread.CurrentThread (). Getcontextclassloader ();             if (ClassLoader = = null)            ClassLoader = Singleton.class.getClassLoader ();             Return (Classloader.loadclass (classname));      }   }

The fix for the second problem is:

  Java code   public class singleton implements java.io.serializable {          public static singleton instance = new  singleton ();                 Protected singleton ()  {                   }         private object readresolve ( )  {                   return instance;            }     }   

public class Singleton implements java.io.Serializable {public      static Singleton INSTANCE = new Singleton ();          Protected Singleton () {            }      private Object readresolve () {               return INSTANCE;         }  

========================================================================

Superheizai students summed up in place:

However, in general, the first is not a single case, the fourth and the third is a kind, if counted, the fifth can also be written separately. Therefore, the general single case is five kinds of writing. Lazy, bad Han, double check lock, enumeration and static inner class.

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.