单例模式进阶

前置文章: http://blog.csdn.net/xiayiguo/article/details/79369480 (单例模式入门与使用)

单例模式实现的不同方式

两个方式的名称比较形象:懒汉式和饿汉式。可以参看下面的代码。懒汉式在于懒,所以直到最后才会生成需要单例对象;而饿汉式由于饿,在类装载的时候就创建了单例对象。

      懒汉式
public class LazySingleton
{
//  step 2 
  private static LazySingleton lazySingleton ;
//  step 1
  private LazySingleton() {

  }
//  step 3 
  public static LazySingleton getInstance () {
      if (lazySingleton == null){
          lazySingleton = new LazySingleton();
      }
      return lazySingleton;
  }
}
     饿汉式
public class HungrySingleton
{

//    step 2 
    private static HungrySingleton hungrySingleton = new HungrySingleton();
//    step 1
    private HungrySingleton() {

    }
//    step 3 
    public static HungrySingleton getInstance () {

        return hungrySingleton;
    }

}

单例的懒汉式实现体现了编程中延迟加载(懒加载)的思想,同时也体现了缓存的思想。

单例模式应用

     缓存实现
public class MyJavaCache
{

    private Map<String, Object> cache = new HashMap<String, Object>();

    public Object getValue(String key) {

        Object object = cache.get(key);
        if (object == null) {
            object = key + "value";
            cache.put(key, object);
        }
        return object;
    }
}

单例模式优缺点

懒汉式是典型的时间换空间,每次获取实例时,都需要进行判断,从而浪费一定的时间,反过来,如果一直没人使用,则不需要节约内存空间。
饿汉式是典型的空间换时间,在类转载时,就创建了类实例,不管你用不用,先创建出来,节约了判断时间。

模式优化

饿汉式是线程安全的,因为虚拟机保证只会装载一次,在类装载的时候是不会发生并发的。
那如何实懒汉式的线程安全呢?可以直接在 getInstance方法上加synchrized 关键字。但这样会降低系统访问速度,而且每次都需要判断。有没有更好的方式呢?

     双重检查加锁

双重检查加锁的意思是,并需要每次进如 getInstance方法都进行加锁,而是先不同步,进入方法后,先判断对象是否存在,如果不存在,才进入同步块,再次检查对象是否存在,如果不存在,创建对象。这样只会在第一次对象存在的情况,进入同步块。 代码示例如下:

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;
    }
}

本文完整代码,可以参见:https://github.com/TrumanXia/design_patterns

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值