单例模式

为什么要有单例模式? 咱也不知道。。

反正单例模式的作用就是保证只创建一个对象。

1)构造函数设置为private,不然没法单例了啊  2)变量声明为静态的,类声明为静态的,这样的才能调用类的方法来创建类的实例

注意: 如果用反射,即便构造函数设置为 private,仍然可以通过反射来创建对象实例 (这里的单例指的是不考虑反射的情况)

1. 懒汉式  (哈哈,我懂了为什么叫懒汉式了,是挺懒的)   线程不安全         【怎么有点通过工厂来获取实例的感觉】

class Singleton{
    private static Singleton singleton=null;
    private Singleton(){};
    public static Singleton getInstance(){
        if(singleton==null){
            singleton=new Singleton();
        }
        return singleton;
    }
}

2. 懒汉式  线程安全    只是在方法上面加入了synchronized进行修饰     当然 synchronized也可以修饰方法中的代码段

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

3. 很明显, 方式2尽管是线程安全了,但是并发度不高,在高并发下显然不合适,所以要优化同步的位置

  采用 dcl  双重检查+锁     注意singlton变量要用valotile来修饰,用来禁止指令重排 

    为对象分配内存空间    实例化数据     引用指向内存空间          【创建对象的三个过程】

  但是如果,第三步排到了第二步的前面,那么引用已经指向内存空间,但是还没有实例化,使用对象时,会出现空指针异常错误。

(由第一个 if  判断导致的,不是第二个 if 判断导致的!!!)

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

4. 静态内部类      

class Singleton{
    private Singleton(){};
    public static Singleton getInstance(){
        return SingletonHolder.singleton;
    }

    static class SingletonHolder{
        private static final Singleton singleton=new Singleton();
    }
}

5. 饿汉式      因为是类变量,所以这里在类加载的时候就行了初始化,不是使用的时候进行的初始化,也就不是懒加载(使用的时候才会创建)

  【有种Spring中的单例和原型之间的感觉】

class Singleton{
    private static final Singleton singleton=new Singleton();
    private Singleton(){};
    public static Singleton getInstance(){
        return singleton;
    }
}

6. 枚举  (这个我也是刚知道。。。学习了,有收获)

 (能够防止  反序列化  和  反射  导致破坏单例模式的问题)

enum EnumSingleton{
    singleton;
    void show(){
        System.out.println("其实不是很难啊!!!");
    }
}

  直接就能用了!!!!

  public static void main(String[] args) {
        EnumSingleton.singleton.show();
    }

 

 

参考文档:

各种单例实现方式:  https://www.cnblogs.com/happy4java/p/11206105.html

 枚举类的安全性: https://blog.csdn.net/whgtheone/article/details/82990139

大佬: https://blog.csdn.net/javazejian/article/details/71333103?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.compare&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.compare

 

posted @ 2020-07-03 18:27  你眼里的星辰  阅读(82)  评论(0)    收藏  举报