单例模式:采用一定的方法,使得软件运行中,对于某个类只能存在一个实例对象,并且该类只能提供一个取得实例的方法。
分类:
- 饿汉式
- 静态常量方式
- 静态代码块方式
- 懒汉式
- 普通方式,线程不安全
- 同步方法方式,线程安全
- 同步代码块方式,线程不安全
- 其他方式
- 双重检查
- 静态内部类
- 枚举
实现思路:
-
想要实现单例,即不能让外部随意的去实例化对象。所以需要构造器私有
-
既然不允许外部去创建了,所以需要在类的内部创建对象
-
外部需要使用对象,所以需要对外提供一个获取实例的方法
一、饿汉式
根据对象创建的时机,可以分为饿汉式和懒汉式。饿汉式,即在类加载的时候立即创建实例,根据所学知识我们可以很快想到要使用关键字将属性和类相关联。以下提供两种书写方式供参考。
特点
- 优点:写法简单,在类装载的时候就完成实例化,避免了线程同步问题
- 缺点:在类装载的时候就完成了实例化,如果开始至终都没有使用这个实例,会造成内存浪费
1.静态常量方式
2.静态代码块方式
这种方式和静态常量的实现方式逻辑和优缺点是一样的,只是写法不同。
二、懒汉式
懒汉式,即在类加载时并不实例化对象,等到使用对象实例的时候才去实例化,也被称为懒加载效果。这样做的好处可以节约资源,减少浪费,只有需要的时候采取创建,不需要就不会实例化。
1.普通方式(线程不安全)
**问题:**在多线程情况下,假设类还未第一次实例化,此时两个进程同时执行到了,而未来得及往下执行时,此时两者校验都成立,都会执行实例化操作,将有可能出现创建多个实例的问题。
2.同步方法方式(线程安全)
既然存在线程安全问题,肯定会想到使用关键字来解决
这样的方式可以起到线程安全的效果,但是每个线程都需要等待锁,所以又会存在效率低的问题,于是有人想到了将锁的范围缩小到方法的内部,使用同步代码块的方式
3.同步代码块方式(线程不安全)
这样的方式好不好呢看代码
这样锁的范围是变小了,但是还会存在多个线程同时判断到,即使在后面加上锁,依旧会在后续创建实例,只是延迟了一点而已,所以这种写法不可取
三、其他方式
1.双重检查
为了能够实现懒加载的效果,同时兼顾效率,于是出现了这种写法
使用双重检查,第一次检查提升效率,第二次检查保证线程安全,简直美滋滋
2.静态内部类
利用静态内部类在被调用时才会加载,即存在懒加载效果,所以也可以这样写
3.枚举
枚举方式是最简单的写法,也是被很多人推崇的写法
简单明了…
四、小结
使用单例模式,可以使一个类只存在一个实例对象,从而节省了系统资源。
上文中列出了8个写法,其中懒加载的写法存在线程安全和效率的问题,需要谨慎使用。比较推荐的写法有5种:懒加载2种+其他方式3种。当认定单例的对象在软件中一定会用到,可以使用懒加载,反之可以使用其他方式
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览92440 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!