您的位置:首页 > 编程语言 > Java开发

java 单例模式的优化与扩展

2014-04-01 17:31 295 查看
单例模式主要的作用就是要控制某个类型的实例的数量是一个而且只有一个.实现单例模式主要有两种类型:一个是饿汉模式,一个是懒汉模式.饿汉模式初始化时就创建.懒汉模式当调用时在创建.这是大家都知道的了.所以不在赘述.这里主要讲一下单例的优化和扩展.懒汉模式是线程安全的,所以会降低访问速度.而且没一次访问都要进行判断.有没有一种方法进行优化.答案是肯定:用一种 叫 双重检查加锁的方法.实现的原理就是在第一次判断为对象为空的时候,在进行加同步锁,然后在判断一次是不是空,如果是空在进行对象的初始化.具体实现代码如下

//双重检查加锁 单例模式.懒加载. volatile 关键字 本地线程不进行缓存. jdk 5以上才可以.
private volatile static  Singleton instance=null;

private Singleton(){}

public static Singleton getInstance(){
//第一次检查,如果为空在进入同步块
if(instance==null){
//当instance为空时进行同步
synchronized (Singleton.class) {
//第二次检查.如果为空在创建instance
if(instance==null){
instance = new Singleton();
}
}
}
return instance;
}


其中注意volatile关键字.它会屏蔽掉JVM中的一些优化代码.所以要慎用.

    还有一种实现方式.既有懒汉模式的优点,又有饿汉模式的优势.即实现了延时加载,有实现了线程安全.这个就是最优模式(相对的最优,没有绝对的最优).这中实现的方式是要借助内部类.而且是静态内部类: 实现的原理是在静态内部类中实现单例模式的初始化.当不用到这个内部类时,是不会进行初始化的,这就实现了延时加载.在内部类中借助JVM来保证线程的安全实现代码如下:

private static class SingletonHoder{
//静态的初始化器
private static Singleton instance = new Singleton();
}

private Singleton(){}

public static Singleton getInstance(){
return SingletonHoder.instance;
}
   还有一种最简单例实现方式.这种方式借助与枚举类进行实现,简单简洁而且安全:实现代码如下:

/**
*
* 利用枚举实现单例模式.
*
*/
public enum Singleton1{
intance;
public void gettest(){}
}


单例模式在应用中不一定就满足程序的需要.可能一个实例是不够用的,需要几个实例.需要几个实例最好呢.一般3个就够了.那么怎么控制单例模式下生产出可控数目的实例:这就要用到简单的缓存,将生成好的实例装入一个简单的缓存中.至于怎样调度最优就不做讨论.实现的代码如下:

private final static String HEADER ="CACHE";//一个自定义的字段作为key的头

private static int num =1;
//最多的实例个数
private static int max_num=3;
//用Map实现的缓存
private static Map<String,Singleton> sigMap = new HashMap<String,Singleton>();

private Singleton(){};

public static Singleton getInstance(){
String key =HEADER+num;
Singleton lt = sigMap.get(key);
if(lt==null){
lt =new Singleton ();
sigMap.put(key, lt);
}
num++;
//大于最大个数就从1开发
if(num>max_num){
num=1;
}
return lt;
}


   单例模式的使用要因场景而异.在给程序节约开销,减少内存的消耗的同时,也会给测试带来麻烦,给程序扩展带来不便.而且它与单一职责原则有冲突
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息