单例模式深入学习

  最近去阿里面试,到第三轮被告知没通过,本人目前工作六年了,自我感觉良好,但是还是无情的被阿里拒绝了,于是痛定思痛,从此潜心学习,夯实基础,摈弃不求甚解,眼高手低的毛病,废话不说,开始今天话题。
  单例模式,通俗的讲,就是某一段时间内,只能存在一个该类的实例,单例模式分为两种,一种是恶汉模式,一种是懒汉模式,先看懒汉模式:

/**
*
*/
package com.goldcard.firmware.upgrade.service;

/**
* @author 1903
*
*/
public class Singleton1 {

private static final Singleton1 singleton=null;

//构造方法必须是私有的
private Singleton1(){

};


public static synchronized  Singleton1 getInstance(){
if(singleton==null){
return new Singleton1();
}
return singleton;
}

}

懒汉模式就是只有用到的时候,才会new 出一个实例,所以称为懒汉模式,记住构造方法必须是私有的,只有这样才能控制使用者不能随意创造实例。

恶汉模式:

/**
*
*/
package com.goldcard.firmware.upgrade.service;

/**
* @author 1903
*
*/
public class Singleton2 {

//提前实例化
public static final Singleton2 singleton=new Singleton2();

private Singleton2(){}


public static Singleton2 getInstance(){

return singleton;
}

}

恶汉模式和懒汉模式的区别是,当jvm 虚拟机加载Singleton2 的时候,就已经把Singleton2 实例化好,供使用者调用。

以上是两种最简单的单例模式,有一种单例模式的演变,叫double check lock,如下


/**
*
*/
package com.goldcard.firmware.upgrade.service;

/**
* @author 1903
*
*/
public class Singleton1 {

private static final Singleton1 singleton=null;

//构造方法必须是私有的
private Singleton1(){

};


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

}

其实这种模式算是懒汉模式的延伸,看看和最上面的区别,其实区别就是把synchronized 从方法上拿走,放在了方法快中,好处是什么呢,肯定性能比第一种要高,因为synchronized 关键字作用在方法上的话,当有线程调用改方法的时候,该类的其他静态方法不能访问。

扩展:
    其实单例模式有很多种实现方式,但是目的只有一个只要能保证实例只有一个就像,想想枚举算不算单例模式,答案是当然的,枚举构造方法都是private的,枚举中的元素都是public static finall来修饰,更关键的是能够防止通过反序列化实例化实例,大家都知道反序列化是不用调用构造函数来创建实例的;
  
   大家都知道spring管理的bean都是单例的,spring容器是怎么管理的,其实就是将实例化好的bean 缓存到map中,让map来保证只能有一个bean的实例,可以去看spring源码。









猜你喜欢

转载自wpf-0604.iteye.com/blog/2313570