阅读 86

Singleton pattern-单例模式

解决问题

保证只生成一个对象的实例

应用场景

仅需要一个对象的场景:比如打印机打印(无论多少任务,一次只打印一个);计时器;线程池等(多项任务共用一个线程池)

原理图

。。。。

示例

单例模式有很多种实现方法。我们举三个经典的例子:

饿汉式

饿汉式是指用之前先准备好。

这里借鉴static 方法

public class SingletonObject {
    private static final SingletonObject instance = new SingletonObject();

    private SingletonObject() {
        
    }
    
    public static SingletonObject getInstance() {
        return instance;
    }
}
复制代码

懒汉式

懒汉式,只有在第一次使用时,我才尝试初始化

public class SingletonObject {
    private static SingletonObject instance = null;

    private SingletonObject() {

    }

    public static SingletonObject getInstance() {
        if (instance == null) {
            instance = new SingletonObject();
        }
        return instance;
    }
}
复制代码

这家伙有个问题是,它是非线程安全的

注册式

这种方式,我们常见于类加载中,其实我们不应该和前面两种并列看待。前面两种都是解决单个对象;注册式目的是为了维护多个对象的单例。

public class SingletonObject {  
    private static Map<String,SingletonObject> map = new HashMap<String,SingletonObject>();  
    static{  
        SingletonObject single = new SingletonObject();  
        map.put(single.getClass().getName(), single);  
    }  
    //保护的默认构造子  
    protected SingletonObject(){}  
    //静态工厂方法,返还此类惟一的实例  
    public static SingletonObject getInstance(String name) {  
        if(name == null) {  
            name = SingletonObject.class.getName();  
            System.out.println("name == null"+"--->name="+name);  
        }  
        if(map.get(name) == null) {  
            try {  
                map.put(name, (SingletonObject) Class.forName(name).newInstance());  
            } catch (InstantiationException e) {  
                e.printStackTrace();  
            } catch (IllegalAccessException e) {  
                e.printStackTrace();  
            } catch (ClassNotFoundException e) {  
                e.printStackTrace();  
            }  
        }  
        return map.get(name);  
    }  
}  
复制代码

参考

https://en.wikipedia.org/wiki/Singleton_pattern