经常面试应聘者时,问及java的懒汉模式的单例模式怎么实现的,很少有人可以真正的答上来,这里我把我理解的单例的概念依依写一下,写的不好欢迎吐槽
首先简单的说下懒汉模式,相对于饿汉模式的区别就是实际用到时才实例化
饿汉模式
public class Singleton {
private Singleton() {
}
private static Singleton instance = new Singleton();
private static Singleton getInstance() {
return instance;
}
}
这个时大家熟知的写法,也是一般人答上来的写法
懒汉模式
第一种 Double check 同步块写法
public class Singleton{
private volatile static Singleton instance; // 声明静态的单例对象的变量, 这里必须加上volatile修饰符
private Singleton(){} //私有构造方法
public static Singleton getSingle(){ //外部通过此方法可以获取对象
if(instance == null){
synchronized (Singleton.class) { //保证了同一时间只能只能有一个对象访问此同步块
if(instance == null){
instance = new Singleton();
}
}
}
return instance; //返回创建好的对象
}
}
思路很
简单,就是我们只需要同步(synchronize)初始化instance的那部分代码从而使代码既正确又很有效率。 这就是所谓的“双检锁”机制(顾名思义)。
volatile修饰的变量,jvm虚拟机能保证从主内存加载到线程工作内存的值是最新的
第二种 内部类写法
public class Singleton
{
private Singleton(){
}
private class SingletonHoledr(){
private static Singleton instance = new Singleton();
}
private static Singleton getInstance(){
return SingletonHoledr.instance;
}
}
内部类式中,实现了延迟加载,只有我们调用了getInstance(),才会创建唯一的实例到内存中.并且也解决了懒汉式中多线程的问题.解决的方式是利用了Classloader的特性. 这种方式也是最近一个同事告知的。相对于第一种懒汉模式,更简洁更佳,另外有种说法第一种方式在不同平台和编译器上可能是无效的,这个说法本人没有去具体考证后,待考证后补充
![](http://7vzrp9.com1.z0.glb.clouddn.com/01.gif)