单例的几种常见写法

小追兵专栏

单例设计模式

第一种:饿汉式

public class Singleton { 
    //实例化该单例对象。 
    private  static Singleton singleton=new Singleton(); 
    //私有化构造方法,使不能在别的类中new对象 
    private Singleton() {  
    }  
    //对外提供的一个获取该实例的方法
    public static Singleton getInstance() {  
       return singleton;  
    }  
} 

常见饿汉式就这种写法,不存在多线程同步等问题。可是存在一个问题,在类被加载的时候,就初始化了对象。即便我们还没想要用这个对象。下面 第三种 我们解决这个问题。

第二种:懒汉式

public class Singleton {  
    //volatile关键字,解决多处理器共享变量问题,防止编译器对代码进行优化,这个关键词的解释较为复杂,可以自行百度
    private volatile static Singleton singleton;  
  
    //私有化构造方法,不让new出其他对象。
    private Singleton() {  
    }  
  
    //暴露的获取这个单例对象的方法
    public static Singleton getInstance() {  
        
        //判断是否被实例化
        if (null == singleton) {  
            //同步锁,放在判断空的里面,是为了解决性能问题,这样只有在new的时候走一次同步锁,不用每次获取实例的时候走到这里。
            synchronized (Singleton.class) {  
                //双重判空,这个必须要有,因为假设第一个线程进入了第一个判空之后,离开了并保存现场,没来得及创建对象,
                //这时第二个线程进入了,顺利的实例化了对象离开了。此时前面离开的线程回来后,又创建了一个对象;
                //这样就有多个对象存在。
                if (null == singleton)  
                    singleton = new Singleton();  
            }  
        }  
        return singleton;  
    }  
}  

第三种:饿汉式升级版

public class Singleton {  
     
    private Singleton() {  
    }  
    public static Singleton getInstance() {  
       return SingletonHolder.SINGLETON;  
    }  

    //静态内部类,解决了我们只有在调用getInstance方法后,才去创建这个单例实例的需求。不会因为加载这个类就创建实例,解决第一种方法的缺点。
    private static class SingletonHolder{  
        private  static Singleton SINGLETON=new Singleton();  
    }  
      
}  

第四种:枚举式

大神为我们提供了一种不太好理解的方法,并且推荐使用。如下。

public enum Singleton {  
    INSTANCE;  
  
    private Singleton() {  
    }  
  
    public String[] getName() {  
        final String[] names = new String[3];  
        names[0] = "小白";  
        names[1] = "小彩";  
        names[2] = "小丽";  
        return names;  
    }  
  
} 
 

在activity中这样调用:

Log.e("猜猜我喜欢谁:",Singleton.INSTANCE.getName()[2]);

注:

  • 我们使用单例,不一定是最好的,因为private构造方法后,可以避免new一个新对象,可是避免不了通过反射机制创建个新对象啊。

  • 还有我们用的说的第一种饿汉式,是在类被加载的时候,创建的实例对象,可是如果有两个类加载器呢,就不能保证对象的唯一性了。

  • 可是我们在必须使用单例的时候,我们为了避免不必要的错误,这里我们优先选择双重锁,静态内部类,大神特别推荐使用枚举。我觉得能高效解决问题的方法就是好方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 单例模式(SingletonPattern)一般被认为是最简单、最易理解的设计模式,也因为它的简洁易懂,是项目中最...
    成热了阅读 9,860评论 4 34
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 32,538评论 18 399
  • 学js和python 练习英语
    安了静了点阅读 1,117评论 0 0

友情链接更多精彩内容