前言
在软件开发的世界里,设计模式如同一本精妙的编码诗集,已经成为一种标准的编程实践。在Java编程中,设计模式很重要。是软件开发中广泛应用的一种编程方法,它可以帮助开发人员更快地编写出高效、可靠和可维护的代码。 本人将制作一个关于Java设计模式的系列文章,总共23种设计模式将以一篇一篇文章讲解,代码笔记已开源:Gitee点击跳转 。本文是这个系列的第一篇章,我们将讲解一下单例模式的实现方式、应用场景以及它的用途。
单例模式
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点供外部代码获取该实例。这种模式的主要目的是限制某个类的实例化过程只能发生一次,避免多次创建相同对象,确保在整个应用程序中只存在一个唯一实例。
应用场景
- 资源管理器: 例如,数据库连接池、线程池等资源的管理,确保全局只有一个资源池。
- 配置管理器: 在系统中负责读取配置信息,保持全局唯一性,避免多次读取配置文件。
- 日志记录器: 用于记录系统日志,保持唯一的记录器实例,确保日志信息一致性。
代码实现
懒汉式
这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。
代码语言:javascript复制public class Singleton {
private static Singleton instance;
public Singleton() {}
public static Singleton getInstance(){
if (instance == null)
instance = new Singleton();
return instance;
}
}
要想懒汉式单例能够在多线程中很好的工作,得对getInstance方法加锁synchronized,但是效率很低。
饿汉式
这种方式是线程安全的方式,因为它是基于 classloader 机制避免了多线程的同步问题。就是有点浪费资源,因为在类加载的时候就初始化了。
代码语言:javascript复制public class Singleton {
private static final Singleton instance = new Singleton();
public Singleton() {}
public static Singleton getInstance(){
return instance;
}
}
静态内部类
这种方式同样利用了 classloader 机制来保证初始化 instance 时只有一个线程。因为SingletonHolder是一个静态内部类,它包含一个静态的INSTANCE成员变量,用于存储单例对象。在第一次调用getInstance方法时,静态内部类会被加载,从而创建单例对象。这种方式既达到了线程安全又兼顾了延迟加载的需求。
代码语言:javascript复制public class Singleton {
public Singleton() {}
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder{
public static final Singleton INSTANCE = new Singleton();
}
}
双重校验锁
这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
代码语言:javascript复制public class Singleton {
private static volatile Singleton instance;
public Singleton() {}
public static Singleton getInstance(){
if (instance == null){
synchronized (Singleton.class){
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
枚举方式
这种方式用的比较少,但这是实现单例模式的最佳方法,它更简洁,自动支持序列化机制,绝对防止多次实例化。
代码语言:javascript复制public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
结尾
一般情况下,不建议使用懒汉式,建议使用饿汉式。只有在要明确实现 lazy loading 效果时,才会使用静态内部类方式。如果涉及到反序列化创建对象时,可以尝试使用枚举方式。如果有其他特殊的需求,可以考虑使用双重校验锁方式。选择哪种实现方式需要根据具体需求来决定,需要综合考虑线程安全、性能、代码复杂度、延迟加载等因素。