Seven ways of writing and precautions for single case mode

Source: Internet
Author: User

First (lazy, thread unsafe):

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

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

second (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; }   }

This kind of writing can work well in multithreading, and it seems to have a good lazy loading, but unfortunately, the efficiency is very low, 99% circumstances do not need synchronization.

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; }   }

This method avoids multithreading synchronization problems based on the Classloder mechanism, however, instance is instantiated when class is loaded, 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 lead to class loading, when initialization instance obviously does not achieve the lazy loading effect.

fourth species ( 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; }   }

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

fifth (Static internal class):

  Java code    public class singleton {       private  static class SingletonHolder {       private static  final singleton instance = new singleton ();        }       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 to initialize the instance, which differs from the third and fourth way (a very subtle difference): The third and fourth Way is if the singleton class is loaded, Then the instance will be instantiated (not reaching the lazy loading effect), and this way is that the singleton class is loaded and instance is not necessarily initialized. Because the Singletonholder class is not actively used, the load Singletonholder class is displayed only when the GetInstance method is called, thus instantiating the instance. Imagine if instantiating instance is consuming resources, I want him to delay loading, on the other hand, I don't want to instantiate the Singleton class when it's loaded, because I can't make sure that the Singleton class can also be actively used in other places to be loaded, Then it is obviously inappropriate to instantiate instance at this time. This is a reasonable way to compare the third and fourth ways.

Sixth (enum):

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

This is the way effective Java author Josh Bloch advocates, not only to avoid multi-threaded synchronization problems, but also to prevent deserialization from recreating new objects, which is a very strong barrier, but Personally think that because of the 1.5 to join the characteristics of the enum, write in this way can not help but feel unfamiliar, in the actual work, I also rarely see someone wrote this.

The 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;        }   }    

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

After JDK1.5, the double check lock can achieve the single case effect normally.

Summary

There are two issues to note:

1. If the singleton is loaded by a different class loader, there may be instances of multiple singleton classes. The assumption is not remote access, for example, some servlet containers use a completely different class loader for each servlet, so that if two servlet accesses a singleton class, they all have their own instances.

2. If the singleton implements the Java.io.Serializable interface, then instances of the class may be serialized and recovered. However, if you serialize an object of a singleton class and then recover multiple objects, you will have multiple instances of the Singleton class.

The way to fix the first problem is to:

  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));         }     }  

The way to fix the second problem is to:

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

For me, I prefer the third and fifth way, easy to understand, and thread-safe in the JVM layer (if not multiple classloader environments), in general, I would use a third way, and only use the fifth way to explicitly implement the lazy loading effect, in addition, When it comes to deserialization to create an object, I try to use enumerations to implement the single example, however, I always guarantee that my program is thread safe, and I will never use the first and second way, and if there are other special needs, I might use the seventh way, after all, JDK1.5 has no problem with double check locking.


In general, however, the first is not a single case, the fourth and third is one, if the calculation, the fifth can also be written separately. Therefore, the general single case are five kinds of writing. Lazy, Evil-han, double check locks, enumerations and static inner classes.


Reproduced from: http://cantellow.iteye.com/blog/838473

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.