单例模式

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一下。

单例模式_第1张图片
test.gif

你可能感兴趣的:(单例模式)