按照加载方式的不同,单例模式有2种实现
1、饿汉式
public class EagerSigleton(){
private static final EagerSigleton m_instatnce=new EagerSigleton();
//私有构造方法
private EagerSigleton(){
}
//静态工厂方法
public EagerSigleton getInstance(){
return m_instatnce;
}
}
2、懒汉式
public class LazySigleton(){
private static final LazySigleton l_instatnce=null;
//私有构造方法
private LazySigleton(){
}
//静态工厂方法
public synchronized LazySigleton getInstance(){
if(l_instatnce==null){
l_instatnce=new LazySigleton();
}
return l_instatnce;
}
}
3、相同点
单列模式属于创建模式,保证在同一个jvm中仅仅存在一个该类的实例。
首先,可以看出,两种方式的构造函数都是私有的。
其次,对外的接口都是工厂方法。
4、不同点
这是最主要的。有两点必须注意:
首先,可以看到。前者m_instatnce是在类装载的时候直接得到该类的实例,可以说是前期绑定的;而后者则是后期绑定的,就是说LazySigleton类加载的时候l_instatnce并没有指向具体的某个对象,而是当调用工厂方法getInstance()的时候才会实例化;
那么这么作,各自的好处是什么呢?显然,前者速度快,后者速度慢;另外,后者可以加载其他的类,也就是动态扩展,灵活性高(注意,此时就不是对这个类的单例了,程序如下所示:)
interface sample{
void dosomething();
}
public class sampleimplement implements sample{
public void dosomething(){
//do something;
}
}
public class LazySigleton(){
private static final sample l_instatnce=null;
//私有构造方法
private LazySigleton(){
}
//静态工厂方法
public synchronized sample getInstance(){
if(l_instatnce==null){
Class c=Class.forName("xxx.sampleimplement");//可以从配置文件得到路径参数
l_instatnce=c.newInstance();
}
return l_instatnce;
}
}
这样就可以根据配置文件配置的smple的实现类路径信息,利用反射机制得到我们希望的单例了。是不是有点用呢。当然这样的单例模式与本意不大一样了。
其次,看看两种单例模式的工厂方法,一个带有synchronized方法,一个则没有。这是需要注意的地方