一:单利模式定义
1.1 定义
单例模式是指保证一个类在任何时刻只有一个实例,单例模式有很多种写法,下面一一加以介绍。
1.2 使用场景
1:确保一个类只有一个实例
2:在整个软件系统中,需要有一个全局的类的实例
二:单例模式实现
2.1 懒汉式
package com.travelsky.pss.tanjie.singleton; /** * 1:保证每个类只有一个实例 * 2:单利类必须自己创建自己的唯一实例 * 3:单利类必须给其它对象提供唯一的实现 * @author tanjie * 单利模式 -- 懒汉式的单利模式,延迟加载所需的对象, 因为只有在需要的时候才会调用getInstance实例化,但是线程不安全 */ public class Singleton01 { //静态修饰变量在类初次加载的时候执行,后面再次加载不会实例化 private static Singleton01 singleton01; //构造方法为private,在同一个JVM里面,避免类在外部被实例化 //但是实际上通过java的反射是可以获取到类的private级别的构造函数,所以其实还是可以被实例化 private Singleton01(){ } public static Singleton01 getInstance(){ if(null == singleton01){ singleton01 = new Singleton01(); } return singleton01; } }
2.2 线程安全的懒汉式
package com.travelsky.pss.tanjie.singleton; /** * 1:保证每个类只有一个实例 * 2:单利类必须自己创建自己的唯一实例 * 3:单利类必须给其它对象提供唯一的实现 * @author tanjie * 单利模式 -- 懒汉式的单利模式,采用synchronized保证线程安全 */ public class Singleton02 { private static Singleton02 singleton01; private Singleton02(){ } public static synchronized Singleton02 getInstance(){ if(null == singleton01){ singleton01 = new Singleton02(); } return singleton01; } }
synchronized关键字保证线程安全,但是在实例化的时候比较耗性能。
2.3 饿汉式单例模式
package com.travelsky.pss.tanjie.singleton; /** * 1:保证每个类只有一个实例 2:单利类必须自己创建自己的唯一实例 3:单利类必须给其它对象提供唯一的实现 * * @author tanjie 单利模式 -- * 饿汉式的单利模式,没有延迟加载所需的对象,在类加载时,就已经创建好了一个静态的对象供外部使用 */ public class Singleton05 { private Singleton05(){ } //在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快,因子在类加载时对象已经初始化了,但是如果第一次加载时 //对象的初始化很耗时,类加载也比较慢 private static final Singleton05 singleton05 = new Singleton05(); public static Singleton05 getInstance(){ return singleton05; } }
饿汉式的单例模式实现是在类加载的时候就讲对象初始化,如果类的加载很耗时,这个方式实现也不好。可以考虑下面的方式实现。
2.4 静态内部类实现
package com.travelsky.pss.tanjie.singleton; /** * 1:保证每个类只有一个实例 * 2:单利类必须自己创建自己的唯一实例 * 3:单利类必须给其它对象提供唯一的实现 * @author tanjie * 单利模式 -- 懒汉式的单利模式,延迟加载所需的对象,因为只有在需要的时候才会调用getInstance实例化,采用静态内部类保证线程安全 效率比加同步高 */ public class Singleton03 { //静态内部类,只会被加载一次 private static class LazyHandler{ private static final Singleton03 instance = new Singleton03(); } private Singleton03(){ } public static final Singleton03 getInstance(){ return LazyHandler.instance; } }
2.5 双重检验锁
package com.travelsky.pss.tanjie.singleton; /** * 1:保证每个类只有一个实例 2:单利类必须自己创建自己的唯一实例 3:单利类必须给其它对象提供唯一的实现 * * @author tanjie 单利模式 -- * 懒汉式的单利模式,延迟加载所需的对象,因为只有在需要的时候才会调用getInstance实例化,采用双重较燕锁保证线程安全 */ public class Singleton04 { private static Singleton04 singleton04; // 构造方法为private,在同一个JVM里面,避免类在外部被实例化 // 但是实际上通过java的反射是可以获取到类的private级别的构造函数,所以其实还是可以被实例化 private Singleton04() { } //采用双重校验锁 public static Singleton04 getInstance() { if (null == singleton04) { synchronized (Singleton04.class) { if (null == singleton04) { synchronized (singleton04) { singleton04 = new Singleton04(); } } } } return singleton04; } }