您的位置:首页 > 编程语言 > Java开发

【Java】单例模式

2015-07-16 14:42 561 查看
如果我们希望一个类只有一个实例,就要用到单例模式。

简单实现

public class SingletonClass {
private static SingletonClass instance = null;

public static SingletonClass getInstance() {
if (instance == null) {
instance = new SingletonClass();
}
return instance;
}
private SingletonClass() {}
}

把类的构造函数写成private,这样其他类就不能实例化这个类,然后在类中提供一个静态的实例返回给使用者。

外部使用者如果想使用SingletonClass类,只能通过getInstance()方法,并且它的构造函数是private的,这样就保证了只能有一个对象存在。

并且,这里把instance初始化为null,直到第一次使用时判断是否为null来创建对象。

想象一下,第一次使用SingletonClass类时,instance为空,然后新建一个对象,返回;

第二次使用时,instance不为空,不再创建对象,直接返回。这样整个过程变成了lazy load,也就是使用时才加载。

但这里有个问题,多线程下,线程A想使用SingletonClass,发现instance是null,于是开始创建实例,这时CPU发生时间片切换,线程B开始执行,线程B也想使用SingletonClass,发现instance是null, 于是创建实例(线程A检测完成后,还没创建出实例)。CPU切换到线程A继续执行,于是,线程A和B都创建了实例,单例模式失败了。

怎么解决呢?

public class SingletonClass {
private static class SingletonClassInstance {
private static final SingletonClass instance = new SingletonClass();
}

public static SingletonClass getInstance() {
return SingletonClassInstance.instance;
}

private SingletonClass() {}
}

在这里使用了Java的静态内部类SingletonClassInstance。
SingletonClass没有static属性,不会被初始化。直到调用getInstance()方法时,会首先加载SingletonClassInstance类,

这个类有一个static的SingletonClass实例,因此需要调用SingletonClass类的构造方法, 然后getInstance()把这个内部类的instance

返回给使用者。由于这个instance是static的,并不会构造多次。

SingletonClassInstance类是私有静态内部类,所以不会被其他类直到。

static语义也要求不会有多个实例存在。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: