概述:单例是设计模式中最常见也最简单的一种设计模式,保证了在程序中只有一个实例存在并且能全局的访问到。比如在android实际APP 开发中用到的,数据库对象(SQLiteOpenHelper)等都会用到单例模式。
常见的单例的几种写法:
一、懒汉式
/** * 懒汉式单例实现的示例 */ public class Singleton { //4:定义一个变量来存储创建好的类实例 //5:因为这个变量要在静态方法中使用,所以需要加上static修饰 private static Singleton instance = null; //1:私有化构造方法,好在内部控制创建实例的数目 private Singleton(){ } //2:定义一个方法来为客户端提供类实例 //3:这个方法需要定义成类方法,也就是要加static public static Singleton getInstance(){ //6:判断存储实例的变量是否有值 if(instance == null){ //6.1:如果没有,就创建一个类实例,并把值赋值给存储类实例的变量 instance = new Singleton(); } //6.2:如果有值,那就直接使用 return instance; } }
|
优点:延迟加载,也就是需要时才回去加载
缺点:线程不安全,在多线程中很容易出现不同步的情况,如在数据库对象进行的频繁读写操作时。
二、饿汉式
/** * 饿汉式单例实现的示例 */ public class Singleton { //4:定义一个静态变量来存储创建好的类实例 //直接在这里创建类实例,只会创建一次 private static Singleton instance = new Singleton(); //1:私有化构造方法,好在内部控制创建实例的数目 private Singleton(){ } //2:定义一个方法来为客户端提供类实例 //3:这个方法需要定义成类方法,也就是要加static //这个方法里面就不需要控制代码了 public static Singleton getInstance(){ //5:直接使用已经创建好的实例 return instance; } }
|
优点:饿汉式是线程安全的,因为虚拟机保证了只会装载一次,在装载类的时候是不会发生并发的。
三、双重检查加锁
public class Singleton { /** * 对保存实例的变量添加volatile的修饰 */ private volatile static Singleton instance = null; private Singleton(){ } public static Singleton getInstance(){ //先检查实例是否存在,如果不存在才进入下面的同步块 if(instance == null){ //同步块,线程安全的创建实例 synchronized(Singleton.class){ //再次检查实例是否存在,如果不存在才真的创建实例 if(instance == null){ instance = new Singleton(); } } } return instance; } }
|
优点:在并发量不多,安全性不高的情况下或许能很完美运行单例模式
缺点:不同平台编译过程中可能会存在严重安全隐患。
四、内部类实现
public class Singleton { /** * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 * 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 */ private static class SingletonHolder{ /** * 静态初始化器,由JVM来保证线程安全 */ private static Singleton instance = new Singleton(); } /** * 私有化构造方法 */ private Singleton(){ } public static Singleton getInstance(){ return SingletonHolder.instance; } }
|
优点:延迟加载,线程安全(java中class加载时互斥的),也减少了内存消耗
五、单例和枚举
/** * 使用枚举来实现单例模式的示例 */ public enum Singleton { /** * 定义一个枚举的元素,它就代表了Singleton的一个实例 */ uniqueInstance; /** * 示意方法,单例可以有自己的操作 */ public void singletonOperation(){ //功能处理 } }
|
优点:无偿的提供了序列化的机制,并由JVM从根本上提供保障,绝对防止多次实例化,
参考链接:研磨设计模式