定义
单例模式(Singleton):一个类 只会创建一个对象实例,且由此类自行创建此类;
特点
- 一个类只会存在一个实例对象
- 该实例对象只能由此类自行创建(构造方法是私有方法)
- 对外提供全局 对象访问方式
优缺点
优点
- 一个类只有一个实例对象,大大节省了内存占用
- 提供对象访问的方式单一,简单已维护
- 实例中资源共享
缺点
- 如果业务逻辑修改,只能通过修改 单例对象代码,扩展困难;不符合”开闭原则“
- 涉及此类的 业务代码一般会在一个类中;容易导致类臃肿
主要组成结构
- 单例类:包含创建实例,提供对外统一访问的 类
- 访问类:使用单例对象的类
应用场景
- 需要频繁实例化,生命周期很短,又会频繁销毁的类;线程池、网络连接池
- 需要对象资源被共享的类;数据库连接池
- 创建对象特别耗时,且经常使用
- … …
代码实现
饿汉模式
/**
* 饿汉式
* 线程安全
*/
class EhanSingleton{
// 创建对象实例
public static EhanSingleton bean = new EhanSingleton();
/**
* 私有构造
*/
private EhanSingleton(){
}
/**
* 提供对象的方法
* @return 单利对象
*/
public static EhanSingleton getBean(){
return bean;
}
}
懒汉模式
/**
* 懒汉 DCL double check lock
* 线程安全
*/
class LHanSingleton{
/**
* 私有化构造
*/
private LHanSingleton(){
}
private static LHanSingleton singleton;
/**
* 提供对象
* @return 单例对象
*/
public static LHanSingleton getInstance(){
// 判断是否已经创建对象
if (singleton == null) {
// 解决线程安全 加锁
// tag:1
synchronized (LHanSingleton.class){
// 再次判空,
// 防止 多个线程 都到了tag:1 的位置,
// 第一个线程创建完bean后 后续线程继续 进入不判断的话 会创建多个
if (singleton == null) {
singleton = new LHanSingleton();
}
}
}
return singleton;
}
}
匿名内部类
/**
* 静态内部类
* 线程安全
*/
class InnerClassSingleton{
/**
* 创建 实例
*/
private static class SingletonHolder {
private static final InnerClassSingleton INSTANCE = new InnerClassSingleton();
}
/**
* 私有化构造
*/
private InnerClassSingleton(){
}
/**
* 提供实例
* @return 单例对象
*/
public static InnerClassSingleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
枚举
/**
* 枚举方式
* 线程安全 无法反序列化 获取新实例
*/
enum EnumSingleton{
INSTANCE;
}