单例模式

单例模式,顾名思义就是只有一个实例,并且自己负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

1、懒汉式:

简介:实例在用到的时候才去创建,判断是否有实例,没有则创建;

缺点:线程不安全,当有多个线程并行调用 getInstance() 的时候,就会创建多个实例。也就是说在多线程下不能正常工作;

解决方法:可以加上synchronized,让其编程线程安全的;

//懒汉式:
public class LazySingle {
    private static LazySingle instance;  //首先不创建对象
    private LazySingle() {}             //不能通过实例化创建对象

    public static LazySingle getinstance(){	//可以加上`synchronized`,使其线程安全
        if (instance == null){
            instance = new LazySingle();   //判断完之后再创建对象
        }
        return instance;
    }
}

2、饿汉式:

简介:实例在初始化的时候就已经建好了,无论你是否都实例,都一样会创建的;线程安全的;

缺点:占用内存空间高,浪费空间;

//饿汉式:
public class HungrySingle {
    private static final HungrySingle instance = new HungrySingle();
    private HungrySingle() { }

    public static HungrySingle getInstance(){
        return instance;
    }
}

3、双检锁模式:

简介:其用了两层判断,既是线程安全的,又不会浪费空间;

问题:在 JVM 的即时编译器中存在指令重排序的优化。即双检锁的运行步骤具有不确定性,结果也无法预测;

解决:在声明变量时加上volatile

//双重锁检验模式:
public class LockSingle {
    private volatile static LockSingle instance; //加上,避免指令重排而导致的多线问题
    private  LockSingle(){ };

    public static  LockSingle getInstance(){
        if (instance == null){              //第一次检验是否实例化对象
            synchronized (LockSingle.class){   //第二次同步锁检验
                if (instance == null){
                    instance = new LockSingle();
                }
            }
        }
        return instance;
    }
}

4、静态内部类模式:

简介:其线程安全,且除了调用该方法之外,没有其他方式可以调用它,读取实例时不会进行同步,没有性能内存的问题;

//静态内部类模式:
public class InnerSingle {
    private static class SingleHolder{
        private static final InnerSingle instance = new InnerSingle();
    }
    private InnerSingle(){};

    public static final InnerSingle getInstance(){
        return SingleHolder.instance;
    }
}

5、枚举模式:

简介:枚举默认就是线程安全的,而且还能防止反序列化导致重新创建新的对象。总之,其他模式所带有的问题,他都可以解决;

//枚举模式:
public enum EnumSingle {
    INSTANCE;
    public EnumSingle getInstance(){
        return INSTANCE;
    }
}
posted @ 2021-11-23 01:26  VXZX  阅读(67)  评论(0)    收藏  举报