详解单例模式

来源:互联网 发布:纸鹤网络验证 编辑:程序博客网 时间:2024/05/22 02:08

定义

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

使用场景

确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个。例如,创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源,这时就要考虑使用单例模式。

分类

饿汉单例模式

public class Singleton {     private static Singleton singleton = new Singleton();     private Singleton(){      }     public static Singleton getInstance(){        return singleton;     }}

懒汉单例模式

public class Singleton {    private static Singleton singleton;    private Singleton(){    }    public static synchronized Singleton getInstance(){        if(singleton ==null){            singleton = new Singleton();            }           return singleton;    }}

Double CheckLock(DCL)实现单例

public class Singleton {    private static Singleton sInstance =null;    private Singleton(){    }    public static Singleton getInstance(){        if(sInstance == null)        {            synchronized (Singleton.class) {                if(sInstance ==null)                {                    sInstance = new Singleton();                }            }        }        return sInstance;    }}

静态内部类单例模式

 public class Singleton {       private Singleton(){       }       public static Singleton getInstance(){           return SingletonHolder.sInstance;       }       private static class SingletonHolder {           private static final Singleton sInstance = new Singleton();       }   }

使用容器实现单例模式

public class Singleton{       private static Map<String,Object> objMap = new HashMap<String,Object>();       private Singleton(){        }       public static void registerService(String key,Object instance) {           if(!objMap.containsKey(key)) {               objMap.put(key, instance);           }       }       public static Object getService(String key) {           return objMap.get(key);       }   }

懒汉为getInstance()方法中添加了synchronized关键字,这是懒汉在多线程情况下保证单例对象唯一性的手段。但即使instance()已经被初始化,每次调用此方法时都会进行同步,这样会消耗不必要的资源,这是懒汉单例模式的最大问题。优点在只有使用时才会被实例化,在一定程度上节约资源。懒汉一般不建议使用。
DCL方式实现单例详解
DCL模式的优点是既能够在需要时才初始化单例,又能够保证线程安全,且单例对象初始化后调用getInstance不进行同步锁。
可以看到getInstance方法中对instance进行了两次判空:第一层判断主要是为了避免不必要的同步,第二层的判断则是为了在null的情况下创建实例。

0 0
原创粉丝点击