3.避免了对资源的多重占用,例如文件操作、数据库连接等。
4.可能存在反射或者反序列化攻击,破坏单例的唯一性。
3.需要保证对象的唯一性和一致性,例如配置信息、全局变量等。
public class Singleton { private Singleton() {} private static Singleton instance; public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }懒汉式:原理是在第一次调用获取实例的方法时,才创建并初始化一个静态的实例对象,然后返回这个实例。为了保证线程安全,需要给获取实例的方法加上synchronized关键字。优点是支持延迟加载,节省资源;缺点是线程不安全,需要加锁,影响性能。
public class Singleton { private Singleton() {} private static final Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } }双重检测:原理是在第一次调用获取实例的方法时,先判断静态的实例对象是否为空,如果为空,则进入同步代码块,再判断一次是否为空,如果为空,则创建并初始化一个静态的实例对象,然后返回这个实例。为了防止指令重排序导致空指针异常,需要给静态的实例对象加上volatile关键字。优点是线程安全,支持延迟加载,不需要加锁;缺点是可能会出现空指针异常,需要使用 volatile 关键字防止指令重排序。
public class Singleton { private Singleton() {} private static volatile Singleton instance; public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }静态内部类:原理是利用了 Java 静态内部类的特性,即外部类加载时不会加载内部类,只有在使用到内部类时才会加载。因此,在第一次调用获取实例的方法时,才会加载静态内部类,并创建并初始化一个静态的实例对象,然后返回这个实例。优点是线程安全,支持延迟加载,不需要加锁;缺点是不能防止反射或者反序列化攻击。
public class Singleton { private Singleton() {} private static class Instance { private static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return Instance.instance; } }枚举类:原理是利用了Java枚举类型本身的特性,即枚举类型在加载时就会创建所有的枚举常量,并且保证了线程安全性和唯一性。因此,在调用获取实例的方法时,直接返回枚举常量即可。优点是线程安全,简单易用,可以防止反射或者反序列化攻击;缺点是不支持延迟加载,不能继承其他类。
public enum Singleton { INSTANCE; }这些不同的实现方式有不同的适用场景,需要根据具体的需求和条件来选择。在这里,我只能给出一些个人的看法,仅供参考:
@Scope("session"):表示该Bean对象的作用域是一个HTTP会话,在同一个会话中只有一个实例。