定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
结构和说明
示例代码
public class SingletonDemo {
/**
* 枚举实现
*/
public static enum SingletonEnum {
/**
* 单例对象
*/
uniqueInstance;
public static SingletonEnum getInstance() {
return uniqueInstance;
}
public void singletonOperation() {
}
@Getter
private String singletonData;
}
/**
* 延迟加载内部类模式
*/
public static class SingletonLazyHolder {
private final static class SingletonHolder {
private final static SingletonLazyHolder uniqueInstance = new SingletonLazyHolder();
}
private SingletonLazyHolder() {
}
public static SingletonLazyHolder getInstance() {
return SingletonHolder.uniqueInstance;
}
public void singletonOperation() {
}
@Getter
private String singletonData;
}
/**
* 饿汉式
*/
public static class SingletonHungry {
private final static SingletonHungry uniqueInstance = new SingletonHungry();
private SingletonHungry() {
}
public static SingletonHungry getInstance() {
return uniqueInstance;
}
public void singletonOperation() {
}
@Getter
private String singletonData;
}
/**
* 懒汉式
*/
public static class SingletonLazy {
private static SingletonLazy uniqueInstance = null;
private SingletonLazy() {
}
public static SingletonLazy getInstance() {
if (uniqueInstance == null) {
synchronized (SingletonLazy.class) {
if (uniqueInstance == null) {
uniqueInstance = new SingletonLazy();
}
}
}
return uniqueInstance;
}
public void singletonOperation() {
}
@Getter
private String singletonData;
}
}
命名建议
一般建议单例模式的方法命名为 getInstance(), 这个方法的返回类型肯定是单例类的类型了。 getInstance() 方法可以有参数,这些参数可能是创建类实例所需要的参数,当然,大多数情况下是不需要的。
调用顺序
饿汉式
懒汉式
优缺点
- 时间和空间
比较上面两种写法: 懒汉式是典型的时间换空间 ,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,那就不会创建实例,则节约内存空间。
饿汉式是典型的空间换时间 ,当类装载的时候就会创建类实例,不管你用不用,先创建出来,然后每次调用的时候,就不需要再判断了,解决了运行时间。
- 线程安全
(1) 不加同步的懒汉式式线程不安全的
(2) 饿汉式是线程安全的
思考
本质
控制实例数目。
何时选用
当需要控制一个类的实例只能有一个,而且客户只能从一个全局访问点访问它时,可以选用单例模式,这些功能恰好是单例模式要解决的问题。