美文网首页
单例模式

单例模式

作者: 养一只tom猫 | 来源:发表于2020-05-01 20:49 被阅读0次

    懒汉式双重检查方式

    class LazySingletonTest {
        private static volatile LazySingletonTest lazySingletonTest;
    
        private LazySingletonTest() {
    
        }
    
        public static LazySingletonTest getInstance() {
            if (lazySingletonTest == null) {
                synchronized (LazySingletonTest.class) {
                    if (lazySingletonTest == null)
                        lazySingletonTest = new LazySingletonTest();
                }
            }
            return lazySingletonTest;
        }
    }
    

    这种方式是通过双重检查+synchronized实现线程安全。
    volatile:防止jvm指令重排
    如果没有加volatile,那么当线程1在进行实例化时,线程2刚好执行到第一层if时,发现实例不为null,但是实例并没有真正初始化完成,那么就会出现空指针。

    懒汉式静态内部类方式

    class LazySingletonTest2{
        static class InnerClass{
            private static LazySingletonTest2 lazySingletonTest2 = new LazySingletonTest2();
        }
    
        private LazySingletonTest2(){}
    
        public static LazySingletonTest2 getInstance(){
            return InnerClass.lazySingletonTest2;
        }
    }
    

    这种方式是借助jvm类加载机制保证线程安全。但是如果通过反射获取该类的构造,通过构造获取对象,再通过静态方法获取对象,则会出现多个实例,不过也很好解决,在构造方法中加一层判断即可。

    class LazySingletonTest2{
        static class InnerClass{
            private static LazySingletonTest2 lazySingletonTest2 = new LazySingletonTest2();
        }
    
        private LazySingletonTest2(){
            if (InnerClass.lazySingletonTest2 != null)
                throw new RuntimeException("不允许创建多个实例");
        }
    
        public static LazySingletonTest2 getInstance(){
            return InnerClass.lazySingletonTest2;
        }
    }
    

    饿汉式:

    /**
     *这种方式最简单
     * 饿汉式1:这种方式是在类加载时,就创建了对象,如果你没有使用到这个对象可能造成内存浪费。
     */
    public class SingletonTest1 {
        public static void main(String[] args) {
            Singleton instance = Singleton.getInstance();
            Singleton instance2 = Singleton.getInstance();
            System.out.println(instance==instance2);
        }
    }
    
    class Singleton{
        private Singleton(){}//私有构造防止new
        private final static Singleton instance = new Singleton();
        public static Singleton getInstance(){
            return instance;
        }
    }
    
    class Singleton1{
        private Singleton1(){}//私有构造防止new
        private static Singleton1 instance;
        
        static {
            instance = new Singleton1();
        }
        public static Singleton1 getInstance(){
            return instance;
        }
    }
    //和上面一模一样,不过是放在静态代码块实例化而已
    

    枚举实现单例:

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public class BeanContainer {
        public BeanContainer getInstance() {
            return BeanContainerHolder.Holder.instance;
        }
    
        private enum BeanContainerHolder{
            /**
             * 存放单例实例
             */
            Holder;
            private BeanContainer instance;
            BeanContainerHolder() {
                this.instance = new BeanContainer();
            }
        }
    }
    

    Java源码中的单例模式


    image.png

    相关文章

      网友评论

          本文标题:单例模式

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