java设计模式之单例模式

单例模式:作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

特点:

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

饿汉式单例类:

特点:典型的空间换时间,不管你用不用都会创建出一个实例

package singleton;

/**
 * 饿汉式单例:典型的空间换时间,不管你用不用都会创建出一个实例
 */
public class EagerSingleton {

    private static EagerSingleton instance = new EagerSingleton();

    /**
     * 构建私有的构造器
     */
    private EagerSingleton(){
        
    }

    /**
     * 静态工厂方法
     * @return
     */
    public static EagerSingleton getInstance(){
        return instance;
    }
}

懒汉式单例类:

特点:典型的时间换空间,需要用到的时候 再创建对象;

package singleton;

/**
 * 懒汉单例:典型的时间换空间,需要用到的时候 再创建对象;
 *      虽然它是线程安全的,但是会降低整个访问的速度,而且每次都要判断。
 */
public class LazySingleton {
    private static LazySingleton instance = null;
    
    private LazySingleton(){
        
    }
    public static synchronized LazySingleton getInstance(){
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

双重检查加锁类:

特点:即实现线程安全,又能够时性能不受很大的影响;

第一重检查:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进行下面的同步块;

第二重检查:进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例;

package singleton;

/**
 * 双重检查枷锁:即实现线程安全,又能够时性能不受很大的影响;
 * 第一重检查:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进行下面的同步块;
 * 第二重检查:进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例;
 * 
 */
public class Singleton {
    //被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能够正确的处理该变量。
    //注意:在Java1.4及以前版本中,很多jvm对于volatile关键字的实现的问题,会导致“双重检查加锁”的失败,因此“双重检查加锁”机制只能用在java5及以上的版本。
    private static volatile Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        //先检查实例是否存在,如果不存在才进入下面的同步代码块
        if (instance == null) {
            //同步块,线程安全的创建实例
            synchronized (Singleton.class) {
                //再次检查实例是否存在,如果不存在才真正的创建实例
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

懒加载内部实现:

特点:实现了延迟加载和线程安全

package singleton;

public class Singleton {
    private Singleton(){}

    /**
     * 类及的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑定关系,
     * 而且只有被调用到时才会装载,从而实现了延迟加载。
     */
    private static class SingletonHolder{
        /**
         * 静态初始化器,由JVM来保证线程安全
         */
        private static Singleton instance = new Singleton();
    }
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

枚举单例类:

特点:

简单、无偿的提供了序列化机制,并由JVM根本上提供保障,绝对防止多次实例化,是更简洁、高效、安全的实现单例的方式。

public enum Singleton {
    /**
     * 定义一个枚举的元素,它就代表了Singleton的一个实例。
     */
    
    uniqueInstance;
    
    /**
     * 单例可以有自己的操作
     */
    public void singletonOperation(){
        //功能处理
    }
}