设计模式—单例模式

定义:确保某一个类只有一个实例, 而且自行实例化向整个系统提供这个实例

优点

  • 由于单例模式在内存中只有一个实例, 减少了内存开支, 特别是一个对象需要频繁地创建、 销毁时, 而且创建或销毁时性能又无法优化, 单例模式的优势就非常明显。
  • 由于单例模式只生成一个实例, 所以减少了系统的性能开销, 当一个对象的产生需要比较多的资源时, 如读取配置、 产生其他依赖对象时, 则可以通过在应用启动时直接产生一个单例对象, 然后用永久驻留内存的方式来解决(在Java EE中采用单例模式时需要注意JVM垃圾回收机制) 。
  • 单例模式可以避免对资源的多重占用 。
  • 单例模式可以在系统设置全局的访问点, 优化和共享资源访问 。

缺点

  • 单例模式一般没有接口, 扩展很困难, 若要扩展, 除了修改代码基本上没有第二种途径可以实现。

  • 单例模式对测试是不利的。

  • 单例模式与单一职责原则有冲突。

使用场景

  • 要求生成唯一序列号的环境 。
  • 整个项目中需要一个共享访问点或共享数据 。
  • 创建一个对象需要消耗的资源过多, 如要访问IO和数据库等资源。
  • 需要定义大量的静态常量和静态方法(如工具类) 的环境, 可以采用单例模式(当然, 也可以直接声明为static的方式)。

注意事项

在高并发情况下, 请注意单例模式的线程同步问题。

案例分析

一个班级只有一个班主任。

  • 线程不安全的懒汉模式:
/**
 * 线程不安全的懒汉模式
 *
 * @author admin
 */
public class ClassTeacher {
    private static ClassTeacher teacher;

    private ClassTeacher() {
    }

    public static ClassTeacher init() {
        if (teacher == null) {
            teacher = new ClassTeacher();
        }
        return teacher;
    }

    public void showMsg() {
        System.out.println("Hello World!");
    }
}
  • 线程安全的懒汉模式
/**
 * 线程安全的懒汉模式
 *
 * @author admin
 */
public class ClassTeacher {
    private static ClassTeacher teacher;

    private ClassTeacher() {
    }

    public synchronized static ClassTeacher init() {
        if (teacher == null) {
            teacher = new ClassTeacher();
        }
        return teacher;
    }

    public void showMsg() {
        System.out.println("Hello World!");
    }
}
  • 线程安全的饿汉模式
/**
 * 饿汉模式
 *
 * @author admin
 */
public class ClassTeacher {
    private static ClassTeacher teacher = new ClassTeacher();

    private ClassTeacher() {
    }

    public void showMsg() {
        System.out.println("Hello World!");
    }
}
  • 双检锁/双重校验锁
/**
 * 双校验
 *
 * @author admin
 */
public class ClassTeacher {
    private static volatile ClassTeacher teacher;

    private ClassTeacher() {
    }

    public static ClassTeacher init() {
        if (teacher == null) {
            synchronized (ClassTeacher.class) {
                if(teacher == null){
                    teacher = new ClassTeacher();
                }
            }
        }
        return teacher;
    }
}
  • 登记式/静态内部类
/**
 * 静态内部类
 *
 * @author admin
 */
public class ClassTeacher {
    private static class ClassTeacherHolder {
        private static final ClassTeacher INSTANCE = new ClassTeacher();
    }

    private ClassTeacher() {
    }

    public static final ClassTeacher init() {
        return ClassTeacherHolder.INSTANCE;
    }
}
posted @   弘一  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
点击右上角即可分享
微信分享提示