美文网首页
单例模式的4种写法

单例模式的4种写法

作者: 蜀山白豆腐 | 来源:发表于2018-02-28 20:31 被阅读0次
    一直知道单例模式有4种,但是都没有写过。在这复习之际把这些东西写一边巩固下基础。
    

    1.饿汉式

    public class Singleton1 {
        private Singleton1() {};//私有的无参构造器
        
        private static Singleton1 instance = new Singleton1();
        
        private static Singleton1 getInstance(){
            return instance;
        }
    }
    

    使用起来简单方便,但是在单例较多的情况下内存占用会比较高。

    2.懒汉式

    public class Singleton2 {
        private Singleton2(){};
        
        private volatile static Singleton2 instance;//加上volite防止指令重排
        
        private static Singleton2 getInstance(){
            if (instance == null) {
                synchronized(Singleton2.class){//加锁防止多线程生成多个实例
                    if (instance == null) {
                        instance = new Singleton2();//指令重排序,先完成赋值,但构造函数还没执行完
                    }
                }
            }
            return instance;
        }
    }
    

    采用了双重检查,线程安全

    用上面的例子,简单复习下volitile的用法 之后有时间可能会写个详细的
    instance = new Singleton2()可以分解为三部分
    1 memory=allocate();// 分配内存
    2 ctorInstanc(memory) //初始化对象
    3 instance=memory //设置instance指向刚分配的地址

    JVM出于优化需要可能进行指令重排就会出现1->3->2的情况,多线程的情况下instance还没有初始化之前其他线程就会在外部检查到instance不为null,而返回还没有初始化的instance,就会有问题

    JVM不会将volatile变量上的操作与其他内存操作一起重新排序,保证检测instance的状态时都是最新的

    3.静态内部类

    public class Singleton3 {
       private Singleton3(){};
       
       private static Singleton3 getInstance(){
           return Holder.instance;
       }
       
       private static class Holder{
           private static Singleton3 instance = new Singleton3();
       }
       
    }
    

    JVM保证在类加载的过程中static代码块在多线程或者单线程下都正确执行,且仅执行一次。内部类不会在类的外部被使用,只有在调用getInstance()方法时才会被加载,解决了延迟加载以及线程安全的问题。

    4.使用枚举

    public enum Singleton4 {
        INSTANCE;
        
        private Singleton4(){};
        
    }
    

    应该是最简单的方法吧,枚举构造函数为私有,不能再创建枚举对象,枚举对象的声明和初始化都是在static块中,由JVM的ClassLoader机制保证了线程的安全性。
    Singleton4.INSTANCE就是类Singleton4的唯一实例。

    相关文章

      网友评论

          本文标题:单例模式的4种写法

          本文链接:https://www.haomeiwen.com/subject/ienbxftx.html