单例模式有两种,一种是懒汉模式,每次在获取实例时都要去判断是否已经被实例化,浪费判断时间。如果一直没人去使用,就不会被实例化,节省内存空间。懒汉模式体现了延迟加载(lazy load),还体现了缓存的思想。缓存是一种典型的空间换时间的方案。在java中map是一种常见的实现了缓存的方式。
另一种是饿汉模式,这种模式在类加载时就被初始化,不管在程序中是否使用的到这种做法浪费了内存空间,但是不需要每次都判断,从而节省了时间。饿汉模式是由JVM保证线程安全的。
懒汉模式不是线程安全的,使用需要时需要加上synchroized关键字来实现线程安全。但这种方式会降低访问时间。每次都需要判断,有一种机制叫“双重检查加锁”。双重加锁将将不会被本地线程缓存,所有对该变量的读写直接操作共享内存,从而确保多个线程正确的处理该变量。
有一种方案叫“Lazy initialization hodler class”这种模式综合运用了java的类级内部类和多线程缺省同步锁,巧妙的实现了延迟加载和线程安全。
以下是大神的代码:
public class Singleton{
/*类级内部类,该内部类的实例与外部类的实例没有绑定关系,只有被调用时被类加载器加载,从而实现了延迟加载
private static class SingletonHolder{
//静态初始化,由JVM来保证线程安全
private stactic Singleton instance = new Sungleton();
}
//私有构造方法
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder .instance ;
}
}
单例的本质是控制实例的数目。当一个实例不够用时,可以使用MAP来缓存多个实例。但在客户端调用时到底使用哪一个可以使用策略模式。
本文出自 “单例模式” 博客,请务必保留此出处http://9060686.blog.51cto.com/9050686/1426967
原文地址:http://9060686.blog.51cto.com/9050686/1426967