In Java, are you sure you have a pair of singleton?

Source: Internet
Author: User
Tags volatile

As a program ape this particular species, have mastered a special ability is the programming idea, logic is more cautious, but sometimes always ignore some details, such as me, always feel that Singleton is the simplest design patterns, do not care too much, but because this is not intended to be a disadvantage in development. Really too Young and simple.
No nonsense, straight into the subject.

In the Code of the world found there are various forms of the single case, some people say that there are 5 kinds of single cases, 6 kinds, 7 kinds ...
For the classification of the singleton this must be regulated, first of all, so many classifications are defined by what, what is the benchmark? Otherwise, there are so many ways to do it.

Thus summed down, from 延迟加载 执行效率 the point of view and the main is divided into two, a hungry man as the name implies is the implementation of high efficiency, but lack of delay loading, other writing is almost a lazy type of an extension, or optimization evolved, see the code below.

Common examples in development--a hungry man
publicclass SingletonDemo1 {    privatestaticfinalnew SingletonDemo1();    publicstaticgetInstance() {        return s1;    }    privateSingletonDemo1() {    }}

Yes, that's right. The above code is called 单例-饿汉式 , a hungry man style has been high efficiency and is known in the single case, so the development of the common Singleton model will choose him, simple and useful.
>

Development evaluation: ★★★★☆
Delay Loading: ★☆☆☆☆
Execution efficiency: ★★★★★

Time-consuming snail-the lazy type
publicclass SingletonDemo2 {    privatestatic SingletonDemo2 s1;    publicstaticsynchronizedgetInstance() {        ifnull) {            new SingletonDemo2();        }        return s1;    }    privateSingletonDemo2() {    }}

In hello world This world, we all know that this kind of singleton is basically not going to be used,

Double check lock-a hungry man type

This can be said to be a microcosm of the above a hungry man style, why so to say, because he is not perfect, still have bugs.

 Public  class SingletonDemo3 {    Private StaticSingletonDemo3 S1; Public StaticSingletonDemo3getinstance() {if(S1 = =NULL) {//The temporary variable is used hereSingletonDemo3 instance;synchronized(Singletondemo3.class) {instance = S1;if(Instance = =NULL) {synchronized(Singletondemo3.class) {if(Instance = =NULL) {instance =NewSingletonDemo3 ();                }} S1 = instance; }            }        }returnS1; }}

This approach is mainly through if to determine non-null instances, improve the efficiency of execution, do not have getInstace to synchronize every time, as long as the first time to synchronize, there is no need to create.

But why is there a bug in this writing? This problem is mainly caused by the internal model of the JVM layer in Java. The simple point is that instance引用的对象有可能还没有完成初始化完就直接返回该实例过去 after the jdk1.5 the problem has been optimized, it is not much to say, you can see this blog is good.
See details

There are, of course, some solutions.
    • Using the volatile keyword to resolve a double-check lock bug, the volatile keyword is another scenario in Java that addresses visibility and ordering issues.
 Public  class safedoublecheckedlocking {//Added volatile keyword    Private volatile StaticInstance Instance; Public StaticInstancegetinstance() {if(Instance = =NULL) {synchronized(Safedoublecheckedlocking.class) {if(Instance = =NULL) Instance =NewInstance ();//instance is volatile, it's no problem now.}        }returnInstance }}

>

Development evaluation: ★★★☆☆
Delay Loading: ★★★☆☆
Execution efficiency: ★★★☆☆

Recommended static inner class-A hungry man type
 Public  class SingletonDemo4 {    //Instantiate an object by means of a static inner class    Private Static  class Innersingleton {        Private Static FinalSingletonDemo4 instance =NewSingletonDemo4 (); } Public StaticSingletonDemo4getinstance() {returnInnersingleton.instance; }Private SingletonDemo4() {    }}

This week is a way to take advantage of some of the characteristics of class loading, in the Classloder mechanism, there is only one thread initialized instance, and this way there is the effect of delay loading, when it SingletonDemo4 is loaded, but the inner class InnerSingleton is not loaded, because InnerSingletonno active use, only the class is loaded by invoking the getInstance method InnerSingleton , and the instance private static final SingletonDemo4 instance = new SingletonDemo4();
So this ingenious way is safer and more efficient than a double-check lock.
>

Development evaluation: ★★★★☆
Delay Loading: ★★★★☆
Execution efficiency: ★★★★☆

Recommended enumeration-A hungry man type
publicenum SingletonDemo5 {    //枚举元素本身就是一个单例(名字可以随意定义);    INSTANCE;    //可以做一些单例的初始化操作    publicvoidsingletonOperation() {    }}

This way is actually very handsome, but in the actual development of very few people used, this is a bit strange, the first enum itself is a singleton, and the enumeration has a feature, you can avoid the serialization and reflection to solve single-case problems, the manager no longer worry about single security, may be 1.5 only enum reason it, If the project is appropriate, you can try this single example.
>

Development evaluation: ★★★★☆
Delay Loading: ★★★★☆
Execution efficiency: ★★★★☆

To summarize:

For each of the following examples, each has its own advantages, and which of these can be selected according to your business needs.

    • A Hungry man
      • Standard A Hungry man (Safety protection aspect enumeration single example better than standard a hungry man)
        Thread-safe, efficient and lazy to load
      • Enumeration single Example
        thread safe, efficient and lazy to load (natural avoidance of reflection and deserialization)
        ?
    • Lazy (Static inner class of efficiency is better than standard idler)
      • Standard lazy
        thread safe, inefficient, lazy to load
      • Double detection (not recommended, bug)
        thread safe, inefficient, lazy to load
      • Static Inner class
        thread safe, inefficient, lazy to load
        ?

In Java, are you sure you have a pair of singleton?

Related Article

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.