美文网首页
3、Singleton单例模式

3、Singleton单例模式

作者: 冰镇柠檬_tree | 来源:发表于2019-04-01 11:11 被阅读0次

    1、定义

    确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例

    2、特点

    • 单例类只能有一个实例。
    • 单例类必须自己创建自己的唯一实例。
    • 单例类必须给所有其他对象提供这一实例。

    3、单例模式可以分为懒汉式和饿汉式

    • 懒汉式单例模式:在类加载时不初始化。
    • 饿汉式单例模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。
    1)懒汉式,线程不安全

    这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。

    public class SingletonDemo1 {
        private static SingletonDemo1 instance;
        private SingletonDemo1(){}
        public static SingletonDemo1 getInstance(){
            if (instance == null) {
                instance = new SingletonDemo1();
            }
            return instance;
        }
    }
    
    2)懒汉式,线程安全
    • 优点:第一次调用才初始化,避免内存浪费。
    • 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
    public class SingletonDemo2 {
        private static SingletonDemo2 instance;
        private SingletonDemo2(){}
        public static synchronized SingletonDemo2 getInstance(){
            if (instance == null) {
                instance = new SingletonDemo2();
            }
            return instance;
        }
    }
    
    3)饿汉式

    基于classloder机制避免了多线程的同步问题,不过,instance在类装载时就实例化,这时候初始化instance没有达到lazy loading的效果。

    • 优点:没有加锁,执行效率会提高。
    • 缺点:类加载时就初始化,浪费内存。
    public class SingletonDemo3 {
        private static SingletonDemo3 instance = new SingletonDemo3();
        private SingletonDemo3(){}
        public static SingletonDemo3 getInstance(){
            return instance;
        }
    }
    
    4)饿汉,变种

    在类初始化即实例化instance

    public class SingletonDemo4 {
        private static SingletonDemo4 instance = null;
        static{
            instance = new SingletonDemo4();
        }
        private SingletonDemo4(){}
        public static SingletonDemo4 getInstance(){
            return instance;
        }
    }
    
    5)登记式/静态内部类

    这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。

    • 利用了classloder的机制来保证初始化instance时只有一个线程.
    • 这种方式是SingletonDemo5 类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance.
    public class SingletonDemo5 {
        private static class SingletonHolder{
            private static final SingletonDemo5 instance = new SingletonDemo5();
        }
        private SingletonDemo5(){}
        public static final SingletonDemo5 getInsatance(){
            return SingletonHolder.instance;
        }
    }
    
    6)枚举

    自动支持序列化机制,绝对防止多次实例化。

    public enum SingletonDemo6 {
        instance;
        public void whateverMethod(){
        }
    }
    
    7)双检锁/双重校验锁(DCL,即 double-checked locking)

    这种方式采用双锁机制,安全且在多线程情况下能保持高性能

    public class SingletonDemo7 {
        private volatile static SingletonDemo7 singletonDemo7;
        private SingletonDemo7(){}
        public static SingletonDemo7 getSingletonDemo7(){
            if (singletonDemo7 == null) {
                synchronized (SingletonDemo7.class) {
                    if (singletonDemo7 == null) {
                        singletonDemo7 = new SingletonDemo7();
                    }
                }
            }
            return singletonDemo7;
        }
    }
    

    相关文章

      网友评论

          本文标题:3、Singleton单例模式

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