SingletonPattern单例模式

单例模式

1.定义

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例

饿汉式单例模式

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

    // 构造器私有化,限制产生多个对象
    private Singleton() {}

    // 对外提供静态方法获取实例对象
    public static Singleton getInstence() {
      return singleton;
    }
}

2.应用

2.1优点

  • 由于单例模式在内存中只有一个实例,减小了内存开支。特别在一个对象需要频繁的创建销毁时,创建销毁时性能无法优化,此时的优势非常明显
  • 由于单例模式只生成一个实例,减少了系统的性能开销。当一个对象需要产生较多的资源时,如读取配置,产生其它以来对象,可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式解决(JavaEE中采用单例模式时需要注意JVM的垃圾回收机制)
  • 单例模式可以避免对同一资源的多重占用,例如写文件操作

2.2缺点

  • 单例模式一般没有接口,扩展性差
  • 单例模式不利于测试。在并行开发环境中,若单例模式没有完成,不能进行测试

2.3使用场景

  • 生成唯一序列号的环境
  • 在整个项目中需要一个共享访问点或共享数据。如一个Web页面上的计数器,使用单例模式保持计数器的值,并确保是线程安全的
  • 创建一个对象时需要消耗的资源过多,如访问IO和数据库等资源
  • 需要定义大量的静态常量和静态方法(如工具类)的环境

2.4注意事项

在该并发情况下,需要注意单例模式的线程同步问题。单例模式有几种不同的实现方式,饿汉式单例模式不会产生多实例的情况,以下方式则需要考虑线程同步问题

懒汉式单例模式

public class Singleton {
    private static final Singleton singleton = null;

    // 构造器私有化,限制产生多个对象
    private Singleton() {}

    // 对外提供静态方法获取实例对象
    public static Singleton getInstence() {
        if (singleton == null) {
          singleton = new Singleton();
        }

        return singleton;
    }
}

懒汉式单例模式在低并发情况下尚不会出现问题,若系统压力增大,并发量增加时可能在内存中存在多个实例。如一个线程A执行到singleton = new Singleton();但还没有获得到对象,此时对象初始化未完成,第二个线程B执行到if (singleton == null) {那么线程B判断条件也为true,于是继续执行下去,则A和B各获得一个对象。

解决单例模式线程不安全的方法,可以在getInstence方法前或方法内加synchronized关键字来实现,建议采用饿汉式单例模式。

3.扩展

有上限的多例模式:产生固定数量对象的模式

public class Singleton {
    // 定义最多能产生的实例数量
    private static int maxNumOfInstance = 2;

    // 定义一个列表容纳所有实例
    private static List<Singleton> singletonList = new ArrayList<>();

    // 定义当前对象实例的序号
    private static int countNumOfInstance = 0;

    // 产生所有的对象
    static {
        for (int i = 0; i < maxNumOfInstance; i++) {
            singletonList.add(new Singleton())
        }
    }

    private Singleton() {}

    public static Singleton getInstence() {
      Random random = new Random();
      countNumOfInstance = random.nextInt(maxNumOfInstance);

      return singletonList.get(countNumOfInstance);
    }
}

考虑到线程安全问题可以使用Vector来代替。采用有上限的多例模式,可以在设计时决定内存中有多少个实例,方便系统扩展,修正单例可能存在的性能问题,提高系统的响应速度。如读取文件,可以在系统启动时完成初始化工作,在内存中启动固定数量的Reader实例。

(0)

相关推荐

  • 面试高频-吃透单例设计模式

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

  • 设计模式(一)——Java单例模式(代码+源码分析)

    设计模式(一)——Java单例模式(代码+源码分析)

  • 设计模式(2) 单例模式

    单例模式 线程安全的Singleton 会破坏Singleton的情况 线程级Singleton 单例模式是几个创建型模式中最独立的一个,它的主要目标不是根据客户程序调用生成一个新的实例,而是控制某个 ...

  • 单例模式

    什么是Singleton? 单例设计模式,即某个类在整个系统中只能有一个实例对象可被获取和使用的代码模式. 例如:代表JVM运行环境的Runtime类. 要点 一是某个类只能有一个实例 构造器私有化 ...

  • 23种设计模式入门 -- 单例模式

    单例模式:采用一定的方法,使得软件运行中,对于某个类只能存在一个实例对象,并且该类只能提供一个取得实例的方法. 分类: 饿汉式 静态常量方式 静态代码块方式 懒汉式 普通方式,线程不安全 同步方法方式 ...

  • 单例模式的八种写法

    单例模式作为日常开发中最常用的设计模式之一,是最基础的设计模式,也是最需要熟练掌握的设计模式.单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点.那么你知道单例模式有多少种实现方式 ...

  • 设计模式之单例模式(Singleton Pattern)

    一.定义 一个类只有一个实例,且该类能自行创建这个实例的一种模式. 二.单例模式举例 例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各 ...

  • 学习单例模式引发的思考

    单例存在哪里问题? 1.单例对oop的支持不友好 OOP 四大特性: 封装 继承 多态 抽象 而单例这种设计模式对于其中的抽象 继承 多态 都支持的不好 为什么这么说呢? 我们先来看一个单例的例子 p ...

  • [软技能] 第99天 你有用过单例模式吗?主要运用场景有哪些?

    今日试题: 你有用过单例模式吗?主要运用场景有哪些? 此开源项目四大宗旨:勤思考,多动手,善总结,能坚持 <论语>,曾子曰:"吾日三省吾身"(我每天多次反省自己). 前 ...

  • 【1/25】将Game改写为单例模式(Singleton Pattern)

    这是<小游戏从0到1设计模式重构>系列内容第1篇,所有源码及资料在"程序员LIYI"公号回复"小游戏从0到1"获取. Game的实例在游戏时只有一个 ...

  • 初级必备:单例模式的7个问题

    故事 实话实说,关于单例模式,网上有N多个版本.你估计也看过很多版本.但看完了又能怎样?我技术群里的一位小伙伴,上周面试,就因为一个单例模式,然后叫他回去等通知了. 下面是这位同学被问到的问题: 1. ...

  • PHP设计模式之单例模式

    PHP设计模式之单例模式 单例模式绝对是在常用以及面试常问设计模式中排名首位的.一方面它够简单,三言两语就能说明白.另一方面,它又够复杂,它的实现不仅仅只有一种形式,而且在Java等异步语言中还要考虑 ...

  • [PHP小课堂]PHP设计模式之单例模式

    [PHP小课堂]PHP设计模式之单例模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料