设计模式笔记1-单例模式

 1、单例模式

        1.1  简介

        所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类 只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。        

        1.2  创建单例模式的八种方法

        方法一:恶汉式1-静态变量(No Lazy)

public class Singleton1 {
    //1.构造器私有化
    private Singleton1() {}

    //2.创建静态对象实例
    private static final Singleton1 INSTANCE = new Singleton1();

    //3.公共方法返回对象实例
    public static Singleton1 getInstance() {
        return INSTANCE;
    }

}

优:装载类的时候完成实例化,避免线程安全问题

缺:非懒加载,会造成内存浪费

结论:可用,但会造成内存浪费

        方法二:恶汉式2-静态代码块(No Lazy)

public class Singleton2 {
    //1.构造器私有化
    private Singleton2() {}

    //2.创建静态变量
    private static Singleton2 INSTANCE;

    //3.使用静态代码块创建实例
    static {
        INSTANCE = new Singleton2();
    }

    //4.公共方法返回对象实例
    public static Singleton2 getInstance() {
        return INSTANCE;
    }
}

优缺点与上面的情况类似

        方法三:懒汉式1-静态方法(线程不安全)

public class Singleton3 {
    //1.构造器私有化
    private Singleton3() {}

    //2.创建静态变量
    private static Singleton3 singleton3;

    //4.公共方法返回对象实例
    public static Singleton3 getInstance() {
        if (singleton3 == null) {
            singleton3 = new Singleton3();
        }
        return singleton3;
    }
}

优:懒加载

缺:线程不安全

总结:不要使用

        方法四:懒汉式2-同步方法(线程安全)

public class Singleton4 {
    //1.构造器私有化
    private Singleton4() {}

    //2.创建静态变量
    private static Singleton4 singleton4;

    //3.公共方法返回对象实例
    public static synchronized Singleton4 getInstance() {
        if (singleton4 == null) {
            singleton4 = new Singleton4();
        }
        return singleton4;
    }
}

优:线程安全

缺:效率低, 每个线程在想获得类的实例时候,执行getInstance()方法都要进行 同步。 

        方法五:懒汉式3-同步代码块(不可实现单例)

public class Singleton5 {
    //1.构造器私有化
    private Singleton5() {}

    //2.创建静态变量
    private static Singleton5 singleton5;

    //3.公共方法返回对象实例
    public static  Singleton5 getInstance() {
        if (singleton5 == null) {
            synchronized (Singleton5.class) {
                singleton5 = new Singleton5();
            }
        }
        return singleton5;
    }
}

本意是对方法四的改进,但是又出现了线程安全问题,不可以使用

        方法六:双重检查-同步代码块

public class Singleton6 {
    //1.构造器私有化
    private Singleton6() {}

    //2.创建静态变量
    //volatile关键字的作用是保证了不同线程之间对共享变量操作时的可见性,
    // 也就是说当一个线程修改volitail修饰的变量,另外一个线程会立即看到最新的值,更利于线程安全
    private static volatile Singleton6 singleton6;

    //3.公共方法返回对象实例
    public static Singleton6 getInstance() {
        if (singleton6 == null) {
            synchronized (Singleton6.class) {
                if (singleton6 == null) {
                    singleton6 = new Singleton6();
                }
            }
        }
        return singleton6;
    }
}

双重检查,对于只有最开始同时进入外层if语句的线程需要同步等待,后续的线程不会进入外层if语句,直接return

        方法七:静态内部类

public class Singleton7 {
    //1.构造器私有化
    private Singleton7() {}

    //2.创建静态内部类
    private static class SingletonInstance {
        private static final Singleton7 INSTANCE = new Singleton7();
    }

    //3.公共方法返回对象实例
    public static Singleton7 getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

利用类装载的机制来保证实例化时只有一个对象,只有调用getInstance()方法,才会加载SingletonInstance类,从而实现懒加载,由于内部类的属性静态INSTANCE只会由装载一次,从而避免了线程不安全(与方法一类似,但是延迟了静态变量的加载)

        方法八:枚举类

public enum Singleton8 {

    INSTANCE;

    public void method() {
        // to do...
    }
}

超级简单,不容易出错

而且枚举类实现了可序列化接口,也能防止反序列化创建新的对象

枚举的属性自带public static final修饰,是static的属性

        1.3  总结

单例模式 懒加载 线程安全 反序列化 推荐使用  

八种单例模式的比较(按顺序)
单例模式懒加载线程安全反序列化推荐使用(等级)
饿汉式1
饿汉式2
懒汉式1
懒汉式2
懒汉式3
双重检查✅✅
静态内部类

✅✅

枚举类✅✅✅

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值