最近学习多线程 发现提到一个单例模式的l检测研究了一下确实发现很麻烦 写下来以备后用
1、饿汉式单例模式 所谓饿汉式就是不管原来有没有上来就新创建一个 不管肚子里面有没有先吃一个再说
public class Singleton {
public static Singleton singleton=new Singleton();
public Singleton(){};
public static Singleton getSingleton(){
return singleton;
}
}
2、饱汉模式单例 所谓饱汉式就是先看下自己吃饱没 没吃饱再吃 吃饱了就直接拍肚
public class Singleton{
public static Singleton singleton=null;
public Singleton(){};
public static Singleton getSingleton()<span style="font-family: Arial, Helvetica, sans-serif;">{</span>
if(singleton==null){
singleton=new Singleton();
}
return singleton;
}
}
饿汉式反应快但是占资源多 饱汉式反应慢 每次都需要检查一下有没有吃饱但是占资源少 为解决饿汉式占资源多的瓶颈出现一种 双重检测的单例模式(有重大缺陷)
3、单例模式的双重检测(双重检测锁定失败的原因是jvm的无序写入 请看代码xxxxxx处 若线程1执行到此处 在构造函数执行之前得到一个非空的对象 线程2再拿的时候是非空 但是不是一个经过赋值的对象)
public class Singleton{
public volatile static Singleton singleton=null;
public Singleton(){};
public static Singleton getSingleton(){
if(singleton==null){
synchronized(Singleton.class){
singleton=new Singleton(); //xxxxxx
}
}
return singleton;
}
}
4、解决单例模式的双重检测 ThreadLocal模式的单例
public class Singleton{
public static final ThreadLocal threadInstance=new ThreadLocal();
public static Singleton singleton=null;
public static getSingleton(){
if(threadInstance.get()==null){
createSingleton();
}
}
public static Singleton createSingleton(){
synchronized(Singleton.class){
if(singleton==null){
singleton=new Singleton();
}
}
}
}
借助了ThreadLocal的全局变量局部化 第一次检测采用线程局部来做如果线程已经访问过则不需要进入同步块