单例模式的主要用运场景,就是系统中需要一个对象实例存在。
1.最简单的一种单例模式(饿汉模式)
public class Single{
public static Single instance = new Single();
private Single(){}
public static Single getInstance(){
return instance;
}
}
这种单例对象是Single类的静态对象,在类装载的时候就实例化了。不管有没有人用,这个instance存在内存中,属于用空间换取时间。
2.线程安全的单例模式简单写法(懒汉模式)
public class Single{
private static Single instance;
private Single(){}
public static synchronized Single getInstance(){
if(instance==null){
instance = new Single();
}
return instance;
}
这种线程安全的单例模式缺点,是每次调用Single.getInstance()时都会进行synchronized同步消耗资源。由于懒汉模式的这个缺点所以产生了,DLC方式实现的单例。
3.DLC (Double Check Lock)fang方式
public class Single{
//volatile关键字的使用,如果不加volatile线程还是不安全的。导致原因由于类的加载机制
private volatile static Single instance = null;
private Single(){}
public static Single getInstance(){
//上来就判断是不已经不为空了,如果已经不为空了直接返回
if(instance==null){
/**1.A,B两个线程instance==null,A先到同步代码块
* 2.则A先判断new 出实例,同步代码块结束,B进入同步代码块
* 3.此时instance!=null,返回A new的实例
*/
synchronized(Single.class){
if(instance==null){
instance = new Single();
}
}
}
return instance;
}
}
4.静态内部类实现单例模式
public class Single{
private Single(){}
public static Single getInstance(){
return SingleInner.instance;
}
public static class SingleInner{
private static final Single instance = new Single();
}
}
第一次加载Single类时不会初始化instance,只有在调用getInstance时才会实例化instance,调用getInstance导致加载SingleInner类。线程安全。
5.枚举单例
public class Single{
public Single(){}
}
public enum SingleImpl{
INSTANCE;
private Single instance;
SingleImpl(){
instance = new Single();
}
public Single getInstance(){
return instance;
}
}
调用时使用SingleImpl.INSTANCE.getInstance()。优点:线程安全,反序列化不会产生新的对象。
网友评论