6种常见的单例模式

作者: 一个番茄柿 | 来源:发表于2017-03-01 23:06 被阅读344次

    1.饿汉式

    类加载的时候就会初始化,他是线程安全的,但是类加载的时候就初始化这样会预先消耗一部分资源。

    /**
     * Created by lijiayi on 2017/3/1.
     * 饿汉式单例
     */
    public class Singleton {
        //生成单例对象
        private static final Singleton mSingleton = new Singleton();
    
        //私有化构造方法
        private Singleton() {
        }
    
        //获取单例对象
        public static Singleton getInstance() {
            return mSingleton;
        }
    }
    
    
    

    2.懒汉式

    当第一次使用的时候才创建对象,合理占用资源,但是当该对象已经创建的时候,调用getInstance()方法会产生不必要的开销,这是懒汉式的一个缺点。

    /**
     * Created by lijiayi on 2017/3/1.
     * 懒汉式单例
     */
    public class Singleton {
        //声明单例对象
        private static Singleton mSingleton;
    
        //私有化构造方法
        private Singleton() {
        }
    
        //同步该方法获取单例对象
        public static synchronized Singleton getInstance() {
            //当该对象为空的时候创建该对象
            if (mSingleton == null) {
                mSingleton = new Singleton();
            }
            //返回该对象实例
            return mSingleton;
        }
    }
    
    

    3.DCL式

    该方式能保证在需要的时候才初始化单例,又能够保证线程安全,而且单例初始化后调用getInstance()不会进行同步锁。

    /**
     * Created by lijiayi on 2017/3/1.
     * DCL单例
     */
    public class Singleton {
        //声明单例对象
        private static Singleton mSingleton;
    
        //私有化构造方法
        private Singleton() {
        }
    
        //同步该方法获取单例对象
        public static synchronized Singleton getInstance() {
            //当该对象为空的时候先同步这个对象
            if (mSingleton == null) {
                synchronized (Singleton.class) {
                    //再判断是否为空
                    if (mSingleton == null) {
                        //如果还空的话 就创建对象
                        mSingleton = new Singleton();
                    }
                }
            }
            //返回该对象实例
            return mSingleton;
        }
    }
    

    4.静态内部类式

    该方式保证了资源预先消耗、不必要的同步、线程的安全问题,还避免了DCL模式在某些情况下失效的问题。所以笔者建议使用该单例模式。

    /**
     * Created by lijiayi on 2017/3/1.
     * 静态内部类单例
     */
    public class Singleton {
    
        //私有化构造方法
        private Singleton() {
        }
    
        //获取单例对象 
        public static Singleton getInstance() {
            //返回内部类中的singleton对象 
            return SingletonHolder.singleton;
        }
    
        /**
         * 静态内部类
         * 第一次加载类的时候不用调用该类,创建singleton对象,
         * 只有调用getInstance()方法时才会创建该对象。
         */
        private static class SingletonHolder {
            private static final Singleton singleton = new Singleton();
        }
    
    }
    

    5.枚举式

    枚举是线程安全的,而且任何情况下都是一个实例,他不能被序列化,也不能被反射,所以枚举单例也是一个不错的选择。

    
    
    /**
     * Created by lijiayi on 2017/3/1.
     * 枚举式单例
     * 枚举单例时线程安全的,在任何情况下都是一个单例
     */
    public enum SingletonEnum {
        //枚举的类型
        INSTANCE;
    
        // 单例中的函数
        public void todoSomethings() {
            System.out.println("do somethings");
        }
    }
    
    //枚举单例的使用
    SingletonEnum.INSTANCE.todoSomethings();```
    ***
    ###6.容器实现单例
    它的好处是可以统一的管理单例,安卓中getSystemService(String name)就是用这种方式实现的。
    ``` java 
    /**
     * Created by lijiayi on 2017/3/1.
     * 容器模式单例
     * 实现了程序中单例的统一管理
     */
    public class SingletonManager {
        private static Map<String, Object> singletonManagerMap = new HashMap<String, Object>();
    
        //私有化构造方法
        private SingletonManager() {
    
        }
    
        //注入程序中的单例
        public static void registerSingleton(String key, Object instance) {
            if (!singletonManagerMap.containsKey(key)) {
                singletonManagerMap.put(key, instance);
            }
        }
    
        //获取对于key值的单例对象
        public static Object getInstance(String key) {
            return singletonManagerMap.get(key);
        }
    }
    

    相关文章

      网友评论

      本文标题:6种常见的单例模式

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