前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式(一)——单例模式

设计模式(一)——单例模式

作者头像
小森啦啦啦
发布2019-07-14 06:23:39
3800
发布2019-07-14 06:23:39
举报
文章被收录于专栏:IT笔记分享

单例模式

在实际生产的项目中我们一般很少自己使用单例模式,但是在有过间接的使用过他,例如spring的bean单例。 定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。构造器私有化,不能被new出来。

项目代码:Github

单例的应用

优点

  1. 在内存中只有一个实例, 减少了内存开支
  2. 当一个对象的产生需要 比较多的资源时, 如读取配置、 产生其他依赖对象时, 则可以通过在应用启动时直接产生一 个单例对象, 然后用永久驻留内存的方式来解决
  3. 单例模式可以避免对资源的多重占用, 例如一个写文件动作, 由于只有一个实例存在 内存中, 避免对同一个资源文件的同时写操作。
  4. 单例模式可以避免对资源的多重占用, 例如一个写文件动作, 由于只有一个实例存在 内存中, 避免对同一个资源文件的同时写操作。

缺点

  1. 单例模式一般没有接口, 扩展很困难;
  2. 单例模式对测试是不利的。 在并行开发环境中, 如果单例模式没有完成, 是不能进行 测试的, 没有接口也不能使用mock的方式虚拟一个对象。
  3. 单例模式与单一职责原则有冲突。

几种单例实现:

1、饿汉模式

代码语言:javascript
复制
public class SingleDemo {
    private static SingleDemo instance = new SingleDemo();
    //私有化构造器
    private SingleDemo() {
        //防止其他通过反射调用构造方法,破解单例
        if (instance != null) {
            throw new RuntimeException();
        }
    }
    //对外提供统一的访问点
    public static SingleDemo getInstance() {
        return instance;
    }
}

优点:

  • 实例的初始化由JVM装载类的时候进行,保证了线程的安全性
  • 实现简单方便,访问效率高

缺点:

  • 不能实现懒加载,资源的利用率不高

2、懒汉模式

代码语言:javascript
复制
public class SingleDemo2 {
    // 此处并不初始化实例
    private static SingleDemo2 instance;

    private SingleDemo2() {
        if (instance != null) {
            throw new RuntimeException();
        }
    }
    /**
     * 当调用此方法的时候才初始化实例, 为了实现线程安全,需要使用同步方法
     */
    public static synchronized SingleDemo2 getInstance() {
        if (instance == null) {
            instance = new SingleDemo2();
        }
        return instance;
    }
}

优点:

  • 只有使用这个类的时候才初始化实例,优化了资源利用率

缺点:

  • 为了实现线程安全,使用了同步方法获取,增加了访问的开销

3、双重检查

代码语言:javascript
复制
public class SingleDemo3 {
    private static SingleDemo3 instance;

    private SingleDemo3() {
        if (instance != null) {
            throw new RuntimeException();
        }
    }

    public static SingleDemo3 getInstance() {
        //第一重检查,提高效率
        if (instance == null) {
            synchronized (SingleDemo3.class) {
                //第二重检查保证线程安全
                if (instance == null) {
                    instance = new SingleDemo3();
                }
            }
        }
        return instance;
    }
}

优点:

  • 实现懒加载
  • 通过缩小同步区域和第一次检查提高访问效率

缺点:

  • 为了实现线程安全,使用了同步方法获取,增加了访问的开销

4、静态内部类

代码语言:javascript
复制
public class SingleDemo4 {
    private static SingleDemo4 instance;

    private static class SingleDemo4Holder {
        private static final SingleDemo4 instance = new SingleDemo4();
    }

    private SingleDemo4() {
        if (instance != null) {
            throw new RuntimeException();
        }
    }

    /**
     * 调用这个方法的时候,JVM才加载静态内部类,才初始化静态内部类的类变量。由于由JVM初始化,保证了线程安全性,
     * 同时又实现了懒加载
     */
    public static SingleDemo4 getInstance() {
        return SingleDemo4Holder.instance;
    }
}

优点:

  • 即实现了线程安全,又实现了懒加载

缺点:

  • 实现稍显复杂

5、枚举类

代码语言:javascript
复制
public enum SingleDemo5 {
     INSTANCE;
    public void someMethod(){

    }
}

优点:

  • 实现简单
  • 线程安全

缺点:

  • 不能实现懒加载

结论

如果需要懒加载就使用静态内部类方式,如果不需要就使用枚举方式

单例模式的扩展

如果要求一个类只能生产固定数量的实例。

代码语言:javascript
复制
public class SingleDemo6{
    // 最多可以生成的单例数量
    private static int maxNumberSingleDemo = 2;
    // 定义列表存放实例
    private static List<SingleDemo6> singleDemoList = new ArrayList<>();

    //生成对象
    static{
        for(int i=0; i<maxNumberSingleDemo; i++){
            singleDemoList.add(new SingleDemo6());
        }
    }

    private SingleDemo6(){}

    public static SingleDemo6 getInstance(){
        Random random = new Random();
        //随机调用一个实例
        int number = random.nextInt(maxNumberSingleDemo);
        return singleDemoList.get(number);
    }

}

这种需要产生固定数量对象的模式就叫做有上限的多例模式, 它是单例模式的一种扩展, 采用有上限的多例模式, 我们可以在设计时决定在内存中有多少个实例, 方便系统进行 扩展, 修正单例可能存在的性能问题, 提供系统的响应速度。 例如读取文件, 我们可以在系 统启动时完成初始化工作, 在内存中启动固定数量的reader实例, 然后在需要读取文件时就 可以快速响应。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT笔记分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单例模式
    • 单例的应用
      • 优点
      • 缺点
      • 1、饿汉模式
      • 2、懒汉模式
      • 3、双重检查
      • 4、静态内部类
      • 5、枚举类
      • 结论
    • 单例模式的扩展
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档