(reproduced) Java design pattern discussion singleton pattern

 

The singleton pattern is a common design pattern in normal project development. It is widely used, and there is a lot of information on the Internet. Xiao Alan also came to join in the fun and make a design pattern related content in the future. Simple start.

The singleton pattern is a pattern for creating objects, which is used to generate a specific instance object of this class. Compared with ordinary object creation, it is a little different. The difference is that it can ensure that a class in the project will only generate A concrete object instance. And the second object instance, the third object instance does not appear. All places where this object instance is used actually use the same object. This is the so-called singleton pattern, which may be unfamiliar to beginners, but it is one of the simplest design patterns for veteran drivers.

 

What are the benefits of using the singleton pattern in Java?

①For frequently used and frequently used objects, you can omit the time it takes to create an object, that is, if there is no object, you need to create a new object. For those heavyweight objects, you can still have one less and one less, and use the old one. The object is just fine, reducing overhead;

②The number of objects created is reduced, and the frequency of system memory usage will be reduced, which will reduce the pressure on GC and shorten the time spent by GC;

③In the process of developing the project, when the class only needs one object instance, then this mode is undoubtedly selected.

 

Singleton implementation 1:

The implementation of a singleton is given below. This implementation is so easy. The code is as follows:

/**
 * Singleton mode
 * @author AlanLee
 *
 */
public class Singleton
{
    
    // Hungry mode 
    private  static Singleton instance = new Singleton();
    
    private Singleton()
    {
        System.out.println("Singleton is create");
    }
    
    public static Singleton getInstance()
    {
        return instance;
    }
    
}

There are a few special caveats to creating singleton objects in this way.

The first point: If we want to ensure that no one in our project accidentally creates redundant object instances, we need to set the constructor of Singleton to private. In this way, other developers cannot create object instances of this class casually, so as to prevent object instances of this class from being created by mistake;

The second point: the instance object must be private and static. If it is not private, the security of the instance cannot be guaranteed. If you are not careful, you may be given Singleton.instance=xxx by other developers, then the object will be changed. If it is = null, it is conceivable that when you use this object instance, you will be greeted by Exceptional embrace of null objects. Secondly, because the factory method getInstance() is a static static method, the variables returned in the method must also be static.

 

Discussion: How does each implementation perform in a high concurrency environment, and what are the shortcomings of each implementation?

The implementation of this singleton mode has very good performance, because the factory method getInstance() simply returns the instance object instance without any lock operation, so in parallel programs, there will still be relatively good performance drops.

But this method has a disadvantage, that is, when the instance object instance is created is out of control. The basic point is that the static member will be created when the class is initialized for the first time, which is not necessarily a factory at this time. When the method getInstance() is called for the first time.

Assuming your singleton pattern is like this, the code is as follows:

/**
 * Singleton mode: the problem of initializing the instance object for the first time
 *
 * @author AlanLee
 *
 */
public class Singleton2
{
    public static int STATUS = 1;

    private static Singleton2 instance = new Singleton2();

    private Singleton2()
    {
        System.out.println("Singleton2 is create");
    }

    public static Singleton2 getInstance()
    {
        return instance;
    }

}

Note that this singleton also contains another static member, STATUS. At this point, referencing this STATUS anywhere will cause an instance of the instance object to be created (any reference to a Singleton2 method or field will cause the class to initialize and create an instance instance, but the class is initialized only once, so the instance instance will never be created. once).

比如:System.out.println(Singleton.STATUS);

The above println will print:

As you can see, new Singleton2() will be called even if we didn't ask to create the instance singleton object.

If you don't care about this small shortcoming, this implementation of the singleton pattern is a good choice. It's easy to implement, the code is easy to read, and it performs well.

 

Singleton implementation 2:

If you want to precisely control the creation time of the instance, then you need to use the following method, a strategy that supports lazy loading, it will only create the object when the instance is used for the first time. code show as below:

/**
 * The lazy mode of the singleton mode
 *
 * @author AlanLee
 *
 */ 
public  class LazySingleton
{
    private static LazySingleton instance = null;

    private LazySingleton()
    {
        System.out.println("LazySingleton is create");
    }

    public static synchronized LazySingleton getInstance()
    {
        if (instance == null)
        {
            instance = new LazySingleton();
        }
        return instance;
    }
}

最初我们并不需要实例化instance对象实例,只有工厂方法getInstance()被第一次调用时才会创建单例对象。但是在高并发环境下,为了防止对象被彼此创建,我们不得不使用synchronized进行方法同步。这种实现的好处是,充分利用了延迟加载,只有在真正需要时才创建对象。但坏处也很明显,并发环境下加锁,在锁竞争激烈的时候会对性能产生一定的影响。

此外,还有一种被称为双重检查模式的方法可以用于创建单例。这是一种非常丑陋、复杂的方法,甚至在低版本的JDK中都不能保证正确性。不推荐使用,也没必要在这种方法上花费太多时间。

 

单例的实现3:

在上述的单例模式实现方式中,可说是各有千秋,那么第三种方式便是结合两者的优势的一种两全其美的实现方式,代码如下:

/**
 * 无懈可击之单例模式
 * 
 * @author Alanlee
 *
 */
public class StaticSingleton
{
    
    private StaticSingleton()
    {
        System.out.println("StaticSingleton is create");
    }

    private static class SingletonHolder
    {
        private static StaticSingleton instance = new StaticSingleton();
    }

    public static StaticSingleton getInstance()
    {
        return SingletonHolder.instance;
    }
    
}

The above code implements a singleton pattern and has the advantages of the first two methods at the same time. First, the factory method getInstance() does not use synchronization locks, which improves performance in high concurrency environments. Second, an instance of StaticSingleton will only be created when the factory method getInstance() is called for the first time. This is a clever use of inner classes and class initialization. The inner class SingletonHolder is declared private, which makes it impossible for us to access and initialize it externally. We can only initialize the SingletonHolder class inside the factory method getInstance(), and use the class initialization mechanism of the virtual machine to create a singleton object.

 

Closing remarks: I'm not afraid of being insulted, and I can watch the flowers bloom and fall in front of the court; I have no intention of going and staying, and the sky is full of clouds and clouds... In addition to reading technical books, Little Alan is also a fan of martial arts fantasy novels! I hope that I can be like the protagonist in the novel on this road of IT. Even if there are many difficulties, I can save myself from danger and achieve prosperity. As for sitting in the arms of beautiful women, little Alan dare not think about it, there is still someone who loves him deeply. Women are enough.

 

Cute Blogger: Alan Lee

Blog address: http://www.cnblogs.com/AlanLee

This article comes from the blog garden, welcome everyone to join the blog garden.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324646211&siteId=291194637