设计模式之 单例模式(哔站学习笔记)

定义:在整个软件系统中,对某个类只能存在一个对象实例

  1. 饿汉式 两种
    1. 静态常量、静态代码块
  1. 懒汉式 三种
    1. 线程不安全;线程安全,同步方法;线程安全,同步代码块
  1. 双重检查
  2. 静态内部类
  3. 枚举
饿汉模式:
  1. 构造器私有化(防止new)
  2. 类的内部创建对象
  3. 向外暴露一个静态的公共方法
class SingleTon{
    // 构造器私有化
    private SingleTon(){}
    // 内部创建对象
    private final static SingleTon instance = new SingleTon();
    // 提供一个共有的静态方法,返回实例对象
    public static SingleTon getInstance(){
        return instance;
    }
}
// 单例模式可用,可能造成内存浪费
// 第二种写法,与上面写法相同
class SingleTon{
    // 构造器私有化
    private SingleTon(){}
    // 内部创建对象
    private static SingleTon instance;
    // 在静态代码块中创建单例
    static{
        instance = new SingleTon();
    }
    // 提供一个共有的静态方法,返回实例对象
    public static SingleTon getInstance(){
        return instance;
    }
}

在main中使用时,直接通过SingleTon.getInstance()获取对象实例,获取到的两个对象实例是同一个对象实例

  1. 在类装载的时候就完成了实例化,没有达到懒加载的效果;如果从始至终没有用到过这个实例,则会造成内存浪费(类装载的情况很多)
懒汉式:
  1. 用到才去创建,不用到就不会去创建
// 第一种懒汉式,线程不安全的
class SingleTon{
    // 构造器私有化
    private SingleTon(){}
    // 内部创建对象
    private static SingleTon instance;
    // 提供一个共有的静态方法,当使用该方法时,才去创建一个实例
    public static SingleTon getInstance(){
        if(instance == null){
            instance = new SingleTon();
        }
        return instance;
    }
}
// ------ 开发时不能使用,有潜在的风险 ------
================================================================
// 第二种懒汉式,加 synchronized 实现线程安全
class SingleTon{
    // 构造器私有化
    private SingleTon(){}
    // 内部创建对象
    private static SingleTon instance;
    // 提供一个共有的静态方法,当使用该方法时,才去创建一个实例
    public static synchronized SingleTon getInstance(){
        if(instance == null){
            instance = new SingleTon();
        }
        return instance;
    }
}
// 本来该类只需要执行一次,
// 但是有了synchronized后,每次获取实例都要进行一次同步
// ------ 开发时不推荐使用,效率太低 ------
================================================================
// 第三种懒汉式
class SingleTon{
    // 构造器私有化
    private SingleTon(){}
    // 内部创建对象
    private static SingleTon instance;
    // 提供一个共有的静态方法,当使用该方法时,才去创建一个实例
    public static SingleTon getInstance(){
        if(instance == null){
            synchronized(SingleTon.class){
                instance = new SingleTon();
            }
        }
        return instance;
    }
}
// 并不能起到线程安全的作用,不能用
双重检查:

解决线程安全的问题,解决了效率的问题

class SingleTon{
    private static volatile SingleTon instance;
    // 构造器私有化
    private SingleTon(){}
    public static SingleTon getInstance(){
        if(instance == null){
            synchronized(SingleTon.class){
                if(instance == null){
                    instance = new SingleTon();
                }
            }
        }
        return instance;
    }
}
// 推荐使用
静态内部类:

外部类装载,静态内部类并不会被立即装载;只有在调用getInstance方法时才会装载,而且只装载一次。(线程是安全的)

class SingleTon{
    // 构造器私有化
    private SingleTon(){}
    // 写一个静态内部类,该类中有一个静态属性 SingleTon
    private static class SingletonInstance{
        private static final SingleTon INSTANCE = new SingleTon(); 
    }
    // 提供一个静态的公有方法,直接返回 SingletonInstance.INSTANCE
    public static SingleTon getInstance(){
        return SingletonInstance.INSTANCE;
    }
}
// 效率高,推荐使用
枚举的方式实现单例模式
enum Singleton{
    INSTANCE;
    public void sayOk(){
        System.out.println("ok~");
    }
}
public static void main(String[] args){
    Singleton singleton_01 = Singleton.INSTANCE;
    Singleton singleton_02 = Singleton.INSTANCE;
    // 以上两个为一个对象,返回的hashCode相同
}
// 推荐使用
// 借助jdk1.5中添加的枚举来实现单例模式,避免了线程同步,防止反序列化重建对象
项目实例

Java中的 Runtime 使用的就是饿汉式

private static Runtime currentRuntime = new Runtime();

public static Runtime getRuntime(){

    return currentRuntime;

}

推荐使用:饿汉式、双重检查、静态内部类、枚举

使用场景:

  1. 频繁进行创建和销毁的对象
  2. 创建对象时耗时过多或耗费资源过多,担忧经常使用到的对象
  3. 工具类对象
  4. 频繁访问数据库或文件的对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值