【设计模式】之单例模式


作者:xcbeyond
疯狂源自梦想,技术成就辉煌!微信公众号:《程序猿技术大咖》号主,专注后端开发多年,拥有丰富的研发经验,乐于技术输出、分享,现阶段从事微服务架构项目的研发工作,涉及架构设计、技术选型、业务研发等工作。对于Java、微服务、数据库、Docker有深入了解,并有大量的调优经验。 







  单例模式(Singleton  Pattern):

  确保某个类只有一个对象。单例类的构造器是私有的(private),避免外界利用构造器直接创建出任意多的实例。由于构造器是private的,因此单例类是不能被继承。

特点:

1>、单例类只能有一个实例。

2>、单例类必须自己创建自己的唯一实例。

3>、单例类必须给所有其他对象提供这一实例。

单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。

1、饿汉式单例

    package 单例模式;
    /**
     * 饿汉式单例:自己将自己实例化
     * 在这个类被加载时,静态变量instance会被初始化,此时类的私有构造器被调用,这时单例类的唯一实例就被创建了。
     * @author xcbeyond
     * @date 2012-5-1 上午11:56:26
     */
    public class EagerSingleton {
        private static final EagerSingleton instance = new                                                 EagerSingleton();
        //私有构造器
        private EagerSingleton() {
        }
        
        public static EagerSingleton getInstance() {
            return instance;
        }
    }


 

2、懒汉式单例

        与饿汉式单例不同的是,懒汉式单例类在第一次被引用时将自己实例化。如果加载器是静态的,那么在懒汉式单例类被加载时不会将自己实例化。

    package 单例模式;
    /**
     * 懒汉式单例
     * @author xcbeyond
     * @date 2012-5-1 下午12:23:54
     */
    public class LazySingleton {
        private static LazySingleton instance = null;
        
        //私有构造器
        private LazySingleton(){
        }
        
        //静态工厂方法,返回此类的唯一实例
        synchronized public static LazySingleton getInstance () {
            if(instance == null ) {
                instance = new LazySingleton();
            }
            return instance;
        }
    }


 

3、登记式单例

         为了克服饿汉式单例类和懒汉式单例类不可继承的缺点,于是引入了登记式单例类。

    package 单例模式;
     
    import java.util.HashMap;
     
    /**
     * 登记式单例类:克服了饿汉式和懒汉式单例类的不可继承的缺点。
     * @author xcbeyond
     * @date 2012-5-1 下午12:35:23
     */
    public class RegisterSingleton {
         private static HashMap reg = new HashMap();
        
        static {
            RegisterSingleton x = new RegisterSingleton();
            reg.put(x.getClass().getName(), x);
        }
        
        //保护的默认构造器
        protected RegisterSingleton () {
            
        }
        
        //静态工厂方法,返回此类唯一的实例
        public static RegisterSingleton getInstance(String name) {
            if(name == null) {
                name = "RegisterSingleton";
            }
            if(reg.get(name)==null) {
                try{
                    reg.put(name, Class.forName(name).newInstance());
                }catch(Exception e) {
                    System.out.println("Error happened");
                }
            }
            return (RegisterSingleton)reg.get(name);
        }
    }