解决问题
保证只生成一个对象的实例
应用场景
仅需要一个对象的场景:比如打印机打印(无论多少任务,一次只打印一个);计时器;线程池等(多项任务共用一个线程池)
原理图
。。。。
示例
单例模式有很多种实现方法。我们举三个经典的例子:
饿汉式
饿汉式是指用之前先准备好。
这里借鉴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);
}
}