四种方式实现单例模式
作为一个编程界的小白,今天学习到了关于单例模式的实现方法,现在分享给想了解相关知识的其他小白,如果有误,就是老师的锅,谢谢指正。
单例模式
一个类中只有一个实例,除此外没有其他的实例模式,有三种特性:
-
构造器不可被外部创建
-
限制了外部的访问方式
-
内部保证实例唯一
现在来介绍四种方式:
public class SingletonPattern01 {
/*懒汉式单例模式*/
private static SingletonPattern01 singletonparrern ;
private SingletonPattern01(){}
public static SingletonPattern01 getSingletonparrern(){
if(singletonparrern==null){
singletonparrern = new SingletonPattern01();
}
return singletonparrern;
}
}
懒汉式就是将自己类的属性和构造方法设为私有,然后将属性设置为静态的,再构造一个静态的方法 SingletonPattern01,以供在其他类调用,在此静态方法中,第一次运行时,用 if 条件判断奔雷的属性 singletonparrern 是否为 null,如果为null,就新建一个实例然后赋值给自己的属性,后来的就判断 singletonparrern 不等于null,然后直接返回一个singletonparrern (第一次就创建好的实例),以此达到单例模式的效果。
public class SingletonPattern02 {
/*饿汉式单例模式*/
private static SingletonPattern02 singletonPattern02 = new SingletonPattern02();
private SingletonPattern02(){}
public static SingletonPattern02 getSingletonPattern(){
return singletonPattern02;
}
}
饿汉式单例模式大致上与上边的懒汉式相同,但饿汉式直接在初始化属性的时候就创建了一个对象然后赋值给了自己的属性,然后通过静态方法返回属性,达到实现单例模式的效果。
public class DCLSingletonPattern {
/*双重检查锁,以懒汉模式为例*/
private static DCLSingletonPattern dclSingletonPattern;
private DCLSingletonPattern(){}
public static DCLSingletonPattern getDclSingletonPattern(){
if(dclSingletonPattern ==null){
synchronized(DCLSingletonPattern.class){
if(dclSingletonPattern ==null){
dclSingletonPattern = new DCLSingletonPattern();
}
}
}
return dclSingletonPattern;
}
}
上述代码,以懒汉模式为例,解决了多线程创建实例的问题,因为不管是懒汉模式,还是饿汉模式,都有可能多个线程运行这个静态方法,从而创建出多个实例,而为代码加锁,就很好地解决了这一问题。
在静态方法中,第一个 if 循环先判断 dclSingletonPattern 是否为空,因为多个线程同时运行这个方法的情况毕竟是少数情况,大多数时间还是会挨个运行,先做判断是否为空,如果不为空就不继续运行,这样就提高了运行效率。如果为空,就先将创建实例的代码锁住,保证线程挨个运行,然后再用第二个 if 语句判断 dclSingletonPattern 是否为空,如果是,就创建一个实例赋值给 dclSingletonPattern ,然后后边的线程就不符合第二个 if 判断要求,从而实现了只创建一个实例的效果。
/** * 枚举式单例,枚举的创建由JVM保证,
因此不会出现并发问题,
构造器自动私有,外部不能创建,
只能引用 * 用法为:SingletonEnum.INSTANCE.doSomething(); */
public enum SingletonEnum {
//唯一实例,默认为public static final的 INSTANCE;
public String name;
public void doSomething(){
System.out.println("doSomething");
}
public static void main(String[] args) {
SingletonEnum.INSTANCE.doSomething();
}
}
枚举式单例模式,我自己也还没搞透彻,在这就不误导大家了,在此贴上老师给的参考代码,以供参考。
希望以上的方法能对各位看客有所帮助,如有错误,请指正,谢谢。