写在前面
五一放假了,大家是不是因为疫情都减少了出门的频率那?不出门我们就一起在家学习吧!下面就让我们从一个问题出发,开始今天的文章吧。你的类有没有“超生”(到处都是该类的实例)那,它是不是也需要“计划生育”(只需要一个实例)啊?什么你不会?没事让我来告诉你解决类“超生”的办法,使用单例设计模式。下面让我们来一起学习一下单例模式。
概述
什么是单例模式?
单例模式是创建类型中常用的一种设计模式。该模式下的类有且仅有一个实例。
优点
1、可以严格控制单例类的使用者怎样以及何时访问唯一的实例。
2、只有一个实例,可以节约系统资源,提高系统的性能,减轻GC的压力。
凡事有利就要弊,单例模式也不可以滥用。
缺点
1、单例模式的扩展性很差,因为没有抽象层。
2、单例模式在一定程度上违背了“单一职责原则”。
不可以将数据库连接池对象设计为的单例类,如果共享连接池对象的程序过多会出现连接池溢出的问题。不可以使用反射,这样会声明出另一个实例。
创建方式
1、饿汉式
提前创建好类的实例不需要等待创建的时间,直接就可以使用。
/**
* 饿汉式(单例模式)
*/
public class HungrySingleton {
// 私有构造方法
private HungrySingleton() {
}
// 创建一个实例
private static final HungrySingleton
HUNGRY_SINGLETON_INSTANCE = new HungrySingleton();
/**
* 获取实例的方法
*/
public static HungrySingleton getHungrySingleton() {
return HUNGRY_SINGLETON_INSTANCE;
}
}
复制代码
该方式可能在还不需要此实例的时候就已经将创建出来了,没有起到懒加载的效果。
2、使用静态内部类
通过使用静态内部类的方式优化上面的饿汉式,起到懒加载的效果。
/**
* 使用静态内部类完成单例模式
*/
public class HungrySingleton {
// 私有构造方法
private HungrySingleton() {
}
// 利用静态类的加载时机实现懒加载
private static class InnerHungrySingleton{
private static final HungrySingleton
HUNGRY_SINGLETON_INSTANCE = new HungrySingleton();
}
/**
* 获取实例的方法
*/
public static HungrySingleton getHungrySingleton() {
return InnerHungrySingleton.HUNGRY_SINGLETON_INSTANCE;
}
}
复制代码
3、懒汉式
在第一次使用时创建实例,使用时需要考虑线程安全问题。
/**
* 懒汉式(单例模式)
*/
public class LazySingleton {
// 私有构造方法
private LazySingleton() {
}
// 私有静态属性
private static LazySingleton lazySingletonInstance;
/**
* 获取实例的方法
*/
public static LazySingleton getLazySingleton() {
// 双重判断
if (null == lazySingletonInstance) {
synchronized (LazySingleton.class) {
if (null == lazySingletonInstance) {
lazySingletonInstance = new LazySingleton();
}
}
}
return lazySingletonInstance;
}
}
复制代码
该方式起到了懒加载的效果,并且也做了线程安全处理。
4、使用枚举
利用枚举的特性让JVM来保证线程安全问题和单一实例的问题。
/**
* 使用枚举实现单例
*/
public enum SingletonEnum {
INSTANCE;
private People people;
SingletonEnum(){
people = new People();
}
public People getPeople() {
return people;
}
// 定义了一个内部类,为了方便代码展示,也可以是一个独立的类。
class People {
}
}
复制代码
使用枚举有一个缺点是需要更多的内存空间。
今天的分享就到这里了,看在我五一放假还坚持分享的份上大家能不能给我点个赞啊?