1.饿汉式单例类
1 /** 2 * 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类 3 * 4 * 单例模式的特点: 5 * 单例类只能有一个实例。 6 * 单例类必须自己创建自己的唯一实例。 7 * 单例类必须给所有其他对象提供这一实例。 8 * @author 开发 9 * 10 * 11 * 饿汉式单例类 12 */ 13 public class EagerSingleton { 14 15 private static EagerSingleton singleton=new EagerSingleton(); 16 17 18 /** 19 * 私有默认构造函数 20 */ 21 private EagerSingleton(){ 22 23 } 24 25 /** 26 * 静态工厂方法 27 * @return 28 */ 29 public static EagerSingleton getInstance(){ 30 return singleton; 31 } 32 33 } 34 /** 35 * 步骤: 36 * 类被加载时,静态变量初始化,调用默认构造器,那么单例类的唯一实例就被创建出来了 37 * 饿汉式是典型的空间换时间 38 */
2.懒汉式单例类
1 /** 2 * 懒汉式单例类 3 * @author 开发 4 * 5 */ 6 public class LazySingleton { 7 8 private static LazySingleton singleton; 9 10 /** 11 * 私有默认构造函数 12 */ 13 private LazySingleton(){} 14 15 /** 16 * 静态工厂方法 17 * @return 18 */ 19 public static synchronized LazySingleton getInstance(){ 20 if(singleton==null){ 21 singleton=new LazySingleton(); 22 } 23 return singleton; 24 } 25 } 26 /** 27 *上面的懒汉式单例类实现了对静态工厂方法同步化,以处理多线程环境 28 * 29 * 30 *懒汉式是时间换空间(线程安全) 31 */
3.双重检查加锁
1 /** 2 * 双重检查加锁 3 * @author 开发 4 * 5 */ 6 public class Singleton { 7 8 private volatile static Singleton instance=null; 9 10 private Singleton(){} 11 12 @SuppressWarnings("unused") 13 private static Singleton getInstance(){ 14 //先检查实例是否存在,如果不存在才进入下面的同步块 15 if(instance==null){ 16 //同步块,线程安全的创建实例 17 synchronized (Singleton.class) { 18 //再次检查实例是否存在,如果不存在才真正的创建实例 19 if(instance==null){ 20 instance=new Singleton(); 21 } 22 } 23 } 24 return instance; 25 } 26 27 } 28 /** 29 *所谓“双重检查加锁”机制,指的是:并不是每次进入getInstance方法都需要同步, 30 *而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进行下面的同步块,这是第一重检查, 31 *进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。 32 *这样一来,就只需要同步一次了,从而减少了多次在同步情况下进行判断所浪费的时间。 33 * 34 *“双重检查加锁”机制的实现会使用关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存, 35 *所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。 36 * 37 *由于volatile关键字可能会屏蔽掉虚拟机中一些必要的代码优化,所以运行效率并不是很高。 38 *因此一般建议,没有特别的需要,不要使用。也就是说,虽然可以使用“双重检查加锁”机制来实现线程安全的单例, 39 *但并不建议大量采用,可以根据情况来选用。 40 */