GOF23—单例模式(1)
核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。
常见的应用场景:
1.Windows的Task Manager(任务管理器)
2.windows的Recycle Bin(回收站)
3.项目中,读取配置文件的类,一般也只有一个对象,没有必要每次使用配置文件数据,每次new一个对象去读取。
4.网站的计数器,也是采用单例模式,这样可以实现同步
5.应用程序的日志应用,一般都采用单例模式进行实现,因为共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
6.数据库连接池的设计也是采用单例设计模式,因为数据库连接是一种数据库资源。
7.操作系统的文件系统,一个操作系统只能有一个文件系统。
8.Application也是单例的典型应用。
9.在Spring中,每个Bean默认是单例的,这样做的优点就是Spring容器可以管理。
10.在servlet,每个servlet也是单例。
11.在Spring MVC/Struts1框架中,控制器对象也是单例
单例模式的优点:
—由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置,产生其他依赖对象时,则可以通过
在启动应用程序时直接产生一个单例对象,然后永久驻留内存的方式来解决。
—单例模式可以在系统设置全局的访问点,优化共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。
常见的五种单例模式实现方式:
—主要:
1.恶汉式(线程安全,调用效率高。但是不可以延时加载)
2.懒汉式(线程安全,调用效率不高,但是可以延时加载)
—其他:
3.双重检测锁式(由于JVM底层内部模型原因,偶尔会出问题,不建议使用)
4.静态内部类式(线程安全,调用效率高,可以延时加载)
5.枚举单例(线程安全,调用效率高,不能延时加载)
恶汉式详细例子:
这样做是立即加载,如果我们这个类不需要instance对象,并且instance对象new的过程时间过长,这样造成了资源浪费。
懒汉式单例模式的例子:
要点:lazy load(懒加载) 延迟加载,用到的时候才会去加载。
问题:资源利用率提高了,但是每一次调用getInstance()方法都要同步,并发效率低。
双重检测锁单例模式例子:
优点:提高了执行效率不用每次都同步,只有第一次才同步,创建之后不需要同步。
问题:由于编译器优化和JVM底层内部模型原因,偶尔会出问题,所以不建议使用。
静态内部类单例设计模式(本质也是一种懒加载)
示例如下:
要点:
—外部类没有static属性,所以不会像恶汉式那样立即加载对象。
—只有真正调用getInstance()才会加载内部类,加载类时,线程是安全的。instance是static final类型,保证了内存中只有一个这样的
实例存在,而且只被赋值一次,保证了线程的安全性。
—兼备了并发高效调用和延时加载的优势。
枚举单例模式例子:
优点:
—实现简单
—枚举本身就是单例模式,由JVM从根本上提供保障,避免通过反射和反序列化的漏洞。
缺点:
—无法延时加载