单例模式有 3 个特点:
- 单例类只有一个实例对象;
- 该单例对象必须由单例类自行创建;
- 单例类对外提供一个访问该单例的全局访问点。
单例模式的优点和缺点
-
单例模式的优点:
- 1.单例模式可以保证内存里只有一个实例,减少了内存的开销。
- 2.可以避免对资源的多重占用。
- 3.单例模式设置全局访问点,可以优化和共享资源的访问。 单例模式的缺点:
- 1.单例模式一般没有接口,扩展困难。如果要扩展,则除了修改原来的代码,没有第二种途径,违背开闭原则。
- 2.在并发测试中,单例模式不利于代码调试。在调试过程中,如果单例中的代码没有执行完,也不能模拟生成一个新的对象。
- 3.单例模式的功能代码通常写在一个类中,如果功能设计不合理,则很容易违背单一职责原则。
单例模式的实现
第 1 种:懒汉式单例
public class LazySingleton {
private static volatile LazySingleton instance = null; //保证 instance 在所有线程中同步
private LazySingleton() {
}
//private 避免类在外部被实例化
public static synchronized LazySingleton getInstance() {
//getInstance 方法前加同步
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
第 2 种:饿汉式单例
public class HungrySingleton {
private static final HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
第 3 种:静态内部类
public class SingletonModel {
private SingletonModel() {
}
private static class singletonHolder{
private final static SingletonModel singletonModel = new SingletonModel();
}
public static SingletonModel getSingletoModel() {
return singletonHolder.singletonModel;
}
}
第 4 种:懒汉式–双重校验
public class SingletonModel {
private static volatile SingletonModel singletonModel = null;
private SingletonModel() {
}
public static SingletonModel getSingletoModel() {
if (singletonModel == null) {
synchronized (SingletonModel.class) {
if (singletonModel == null) {
singletonModel = new SingletonModel();
}
}
}
return singletonModel;
}
}
第 5 种:枚举
public class Singleton {
private Singleton(){
}
public static enum SingletonEnum {
SINGLETON;
private Singleton instance = null;
private SingletonEnum(){
instance = new Singleton();
}
public Singleton getInstance(){
return instance;
}
}
}
单例模式的扩展
单例模式可扩展为有限的多例(Multitcm)模式,这种模式可生成有限个实例并保存在 ArrayList 中,客户需要时可随机获取,其结构图如图 所示。