单例模式

作者: imyyq_star | 来源:发表于2017-03-08 10:53 被阅读36次

    1、单线程的单件模式:

        private static Singleton singleton;
        /**
         * 这种方式在多线程中是有问题的,可能产生多个实例
         */
        public static Singleton getInstance()
        {
            if (singleton == null)
            {
                singleton = new Singleton();
            }
            return singleton;
        }
        ```
    # 2、多线程(线程同步)的单件模式:
    
    /**
     * 使用 synchronized 迫使每个线程在进入这个方法前,都要等待其他线程离开这个方法。
     * 
     * 缺点是:只有第一次执行的时候,才真正需要同步,一旦实例化好,就不需要再同步了,造成性能累赘
     * 
     * 如果这种累赘对程序没多大影响,那就用
     */
    public static synchronized Singleton getInstance()
    {
        if (singleton == null)
        {
            singleton = new Singleton();
        }
        return singleton;
    }
    
    # 3、急切的单件模式:
    
    // 在JVM加载这个类的时候,马上创建此类实例,这种急切创建实例的方式,适用于那种总是创建和使用实例的程序
    private static Singleton singleton = new Singleton();
    public static Singleton getInstance()
    {
        return singleton;
    }
    
        
    # 4、双重加锁的单件模式:
    
    private volatile static Singleton singleton;
    /**
     * 利用双重加锁,这样只有在第一次实例化时,才会加锁
     * 
     * 如果性能是你关心的重点,这个方法适合,但是,此方式不适用于1.4及更早的版本中。1.5之后可以达到正常的单例效果。
     */
    public static Singleton getInstance()
    {
        if (singleton == null)
        {
            synchronized (Singleton.class)
            {
                if (singleton == null)
                {
                    singleton = new Singleton();
                }
            }
        }
        return singleton3;
    }
    
    # 5、如果类自给自足,不依赖于复杂的初始化,可以把类的变量和方法都置为静态,把类当成单件使用。
    
    
    # 6、类加载器:两个类加载器可能有机会各自创建自己的单例
        每个类加载器都定义了一个命名空间,如果有两个以上的类加载器,不同的类加载器可能会加载同一个类,造成多个单件。
        这时候就需要小心了,可以通过自行指定类加载器,并指定同一个类加载器
    
    
    
    # 7、枚举:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象
        public enum Singleton
        {
            INSTANCE;
    
            public void whateverMethod()
            {
            }
        }
    
    # 8、内部类的形式:
        public class Singleton
        {
            private static class SingletonHolder
            {
                private static final Singleton INSTANCE = new Singleton();
            }
    
            // 只有此方法被调用,SingletonHolder类才会被加载。能做到单例并且延迟加载。
            public static final Singleton getInstance()
            {
                return SingletonHolder.INSTANCE;
            }
        }
    
    ---
    
    ** 如果是类的形式,都需要私有构造器 **
    
    private Singleton()
    {
    }
    
    
    ** 本人最常用的是第4和第8种,如果你的IDE使用的是AndroidStudio,可以定义一个Live Templates。如下:**
    (1)打开Settings -> Editor -> Live Templates
    (2)添加一个Live Template,这里设定名称为single_yyq
    (3)在No applicable contexts. ** Define **,点击Define,勾选Java
    (4)在Template text中输入:
    

    private static $classname$ instance;

    private $classname$()
    {
    }
    
    public static $classname$ getInstance()
    {
        if (instance == null)
        {
            synchronized ($classname$.class)
            {
                if (instance == null)
                {
                    instance = new $classname$();
                }
            }
        }
        return instance;
    }
    
    (5)点击右边的Edit variables,将classname的类型改为className(),大功告成,Live Templates的用处不言而喻啦,有兴趣可以Google一下。
    
    
    ![test.gif](https://img.haomeiwen.com/i2691199/8529b1a52470c995.gif?imageMogr2/auto-orient/strip)
    

    相关文章

      网友评论

        本文标题:单例模式

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