[ 设计模式笔记 ] 3.单例模式

单例模式

总结:

在这里插入图片描述


介绍

        保证在整个软件系统中,对某个类对象只能存在一个实例,并且提供一个取得其对象实例的方法。


饿汉式

静态常量方式

实现

        构造器私有化,属性位置创建实例的静态变量, 提供静态方获取静态实例。

public class Single {
    // 构造器私有化
    private Single(){}

    // 静态实例
    private final static Single instance = new Single();

    // 静态方法获取
    private static Single getInstance() {
        return instance;
    }
}

优点:

        写法比较简单,在类装载的时候就完成了实例化。避免了线程同步问题。

缺点:

        在类装载的时候完成实例化,没有达到Lazy Loading的效果,如果从始至终没有使用过这个实例,则会造成内存的浪费

结论:

静态代码块儿方式

        这种方式也是在类加载时候进行实例的new, 因此优点和缺点和静态常量方式一致。

实现

package club.fsociety.singleton;

public class Single2 {
    // 构造器私有化
    private Single2(){ }

    // 静态实例
    private static Single2 instance;

    // 静态代码快儿
    static {
        instance = new Single2();
    }

    // 静态方法获取
    private static Single2 getInstance() {
        return instance;
    }
}

懒汉式

        解决Lazy Loading的问题。

线程不安全的方式

实现:

package club.fsociety.singleton;

public class Single3 {

    // 私有构造器
    private Single3(){}

    // 静态成员
    private static Single3 instace;

    // 获取实例的方法
    private static Single3 getInstace() {
        if(null == instace)
            instace = new Single3();
        return instace;
    }
}

优点:

         实现了Lazy Loading

缺点:

         线程不安全,可能多个线程同时判定为未创建,后进行创建,会导致多创建出来几个实例。

结论:

         了解其存在的问题,开发中不要使用

线程安全方式:

实现

         使用了同步代码块来修饰获取实例的方法:

package club.fsociety.singleton;

public class Single3 {

    // 私有构造器
    private Single3(){}

    // 静态成员
    private static Single3 instace;

    // 获取实例的方法
    private static synchronized Single3 getInstace() {
        if(null == instace)
            instace = new Single3();
        return instace;
    }
}

优点

         即解决了饿汉中存在的Lazy Loding问题,又解决了线程安全问题。

缺点

         getInstance方法频繁调用下会导致效率地下。

结论

         在实际开发中不推荐使用。


DoubleCheck

实现

package club.fsociety.singleton;

public class Single4 {

    // 私有构造器
    private Single4(){}

    // 静态成员
    private static Single4 instace;

    // 获取实例的方法
    private static  Single4 getInstace() {
        if(null == instace) {
            synchronized (Single4.class) {
                if(null == instace)
                    instace = new Single4();
            }
        }
        return instace;
    }
}

优点

   &nbsp    即解决了Lazy Loading 和 线程安全问题,又避免每次getInstance的时候都执行一遍同步代码块儿。

缺点

   &nbsp    

结论:

        强烈推荐使用。


静态内部类方式

实现方式

        外部类被装载的时候,静态内部类不会被装载。当调用外部类获取静态内部类方法时候再装载静态内部类,且静态内部类被装载后会初始化静态代码,且线程安全。这样既能解决线程安全问题,也能解决Lazy Loading问题。

package club.fsociety.singleton;

public class Single5 {

    // 私有化的构造
    private Single5(){}

    // 静态内部类
    private static class Single5Instance {
        private static final Single5 instance = new Single5();
    }

    // 获取实例方法
    public static Single5 getInstance() {
        return Single5Instance.instance;
    }
}

优点:

        解决线程安全,和LazyLaoding问题,且效率高。

结论

        推荐使用。


枚举

实现方式:

        JDK1.5中添加的枚举来实现单例模式,因为枚举当中的每个枚举元素本声就是自身的一个实例的单例,刚好可以直接借助来实现单例模式。

public enum Single6 {
    INSTANCE;
    public void method() {
        System.out.println("这是一个实例方法");
    }
}

优点

        能避免多线程同步问题,而且还能防止反序列化重新创建的对象。其为最推荐的方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章