Transfer: [HeadFirst Design Pattern Study Notes] 5 Singleton Pattern

original source

http://www.cnblogs.com/gnuhpc/archive/2012/12/17/2822409.html

1. The singleton pattern ensures that an instance is created, and there is only one object at any time. It gives us a global access point and shields the shortcomings of global variables. Can be used to manage shared resources such as database connections or thread pools. The feature is that the constructor is private, and then declares a private static member as a class object, and provides a static class method to create the object. When creating an object, it will first determine whether it has been created. If so, it will directly return the created object. If not, then Create new objects.

2. The classic singleton pattern is as follows:

public class Singleton { 
    private static Singleton uniqueInstance; 
    // other useful instance variables here 
    private Singleton() {} 
    public static Singleton getInstance() { 
        if (uniqueInstance == null) { 
            uniqueInstance = new Singleton(); 
        } 
        return uniqueInstance; 
    } 
    // other useful methods here 
}

This is thread-unsafe, because at the same time, two threads may enter getInstance to create a new Singleton, resulting in no guarantee of uniqueness.

3. The singleton pattern of multi-thread safety is as follows:

public class Singleton { 
    private static Singleton uniqueInstance; 
    // other useful instance variables here 
    private Singleton() {} 
    public static synchronized Singleton getInstance() { 
        if (uniqueInstance == null) { 
            uniqueInstance = new Singleton(); 
        } 
        return uniqueInstance; 
    } 
    // other useful methods here 
}

Using a synchronized  qualifier to synchronize the method of creating an instance can fulfill the requirement of thread safety, but if it has been created, the synchronization is redundant and inefficient. If the program does not pay attention to the efficiency of this part, this method can be used.

4. If you always use the singleton mode, you can use the "eager" method to call the singleton mode, taking advantage of the feature that the instance will be created immediately when the JVM loads the class, which ensures thread safety, but this has the same effect as the global one. The same problem with variables - if this object consumes a lot of resources, and the program has not used it during execution, it will cause a waste of resources:

public class Singleton { 
private static Singleton uniqueInstance = new Singleton(); 
    private Singleton() {} 
    public static Singleton getInstance() { 
        return uniqueInstance; 
    } 
}

5. A more comprehensive way is to use "double-checked locking" to reduce the number of synchronizations while maintaining thread safety. Note that the volatile keyword is not supported before JAVA5 .

public class Singleton { 
    private volatile static Singleton uniqueInstance;//volatile 确保当uniqueInstance初始化为Singleton的实例时,多个线程可以正确的处理uniqueInstance变量。 
    private Singleton() {} 
    public static Singleton getInstance() { 
        if (uniqueInstance == null) {//只有第一次才会执行这里面的代码。也就是说第一次为同步,后来就是不作为了——这就是我们要的效果。 
            synchronized (Singleton.class) { 
                if (uniqueInstance == null) { 
                    uniqueInstance = new Singleton(); 
                } 
            } 
        } 
        return uniqueInstance; 
    } 
}

6.注意事项:

1)单例类不能被继承,因为Java中私有构造方法的无法扩展类。

2)和全局变量相比的优缺点,请参照“急切”和“延迟”两种单件模式实现的方式进行类比分析。

3)若使用多个类加载器,则可能导致单例失效。

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326847961&siteId=291194637