通州区网站建设,多平台网页制作,wordpress主题怎么编辑,做情网站单例模式 单例模式#xff0c;就是一个类在任何情况下绝对只有一个实例#xff0c;并且提供一个全局访问点来获取该实例。 要实现单例#xff0c;至少需要满足两个点#xff1a; 私有化构造方法#xff0c;防止被外部实例化造成多实例问题 提供一个静态方位作为全局访问点…单例模式 单例模式就是一个类在任何情况下绝对只有一个实例并且提供一个全局访问点来获取该实例。 要实现单例至少需要满足两个点 私有化构造方法防止被外部实例化造成多实例问题 提供一个静态方位作为全局访问点来获取唯一的实例对象 在 Java 里面至少有 6 种方法来实现单例。 实现 第一种 第一种, 是最简单的实现通过延迟加载的方式进行实例化并且增加了同步 锁机制避免多线程环境下 的线程安全问题. public class Singleton {private static Singleton instance;private Singleton(){}public static synchronized Singleton getInstance(){if (instance null){instancenew Singleton();}return instance;}
} 但是这种加锁会造成性能问题而且同步锁只有在第一次实例化的时候才产生作用后续不需要。 第二种
第二种,通过双重检查锁的方式减少了锁的范围来提升性能
public class Singleton {private volatile static Singleton instance;private Singleton() {// 私有构造函数}public static Singleton getInstance() {if (instance null) {synchronized (Singleton.class) {if (instance null) {instance new Singleton();}}}return instance;}
}instance 使用 volatile 关键字修饰以确保多线程环境下的可见性和有序性。 使用volatile关键字修饰instance变量主要是为了保证在多线程环境下获取单例实例的可见性和有序性。具体来说 可见性当一个线程第一次访问getInstance()方法时如果instance为null那么该线程将进入同步块并创建实例。这个写操作对于其他线程来说是可见的即它们将立即看到instance的新值。这就避免了在一个线程创建实例后其他线程仍然看到instance为null的情况。 有序性在双重检查锁中由于编译器和处理器的优化行为可能会发生指令重排序。如果没有使用volatile关键字修饰instance那么在某些情况下其他线程可能会看到指令重排后的顺序从而导致单例实例的未完全初始化。而使用volatile修饰instance后禁止了这种指令重排序优化保证了实例的完整性。 第三种 第三种通过饿汉式实现单例。这种方式在类加载的时候就触发了实例化从而避免了多线程同步问题。 public class Singleton {private static Singleton instancenew Singleton();private Singleton(){}public static Singleton getInstance(){return instance;}}
第四种 第四种通过在静态块里面实例化而静态块是在类加载的时候触发执行的所以也只会执行一 次。 public class Singleton {private static Singleton instance null;static {instancenew Singleton();}private Singleton(){}public Singleton getInstance(){return instance;}} 上面两种方式都是在类加载的时候初始化没有达到延迟加载的效果当然本身影响不大。 第五种 由于静态内部类只有调用静态内部类的方法静态域或者构造方法的时候才会加载静态内部类。 public class Singleton {private static class SingletonHolder{private static final Singleton INSTANCEnew Singleton();}private Singleton(){}public static final Singleton getInstance(){return SingletonHolder.INSTANCE;}
} 所以当 Singleton 被加载的时候不会初始化 INSTANCE从而实现了延迟加载。 第六种 我们还可以使用枚举类来实现。 public enum Singleton {INSTANCE;// 添加其他成员变量和方法public void doSomething() {// 单例实例的操作}
} 这种写法既能避免多线程同步问题又能防止反序列化重新创建新对象也是一个比较好的方案。 总结 我认为大体分为 3 种方式来实现单例 第一种是通过双重检查锁的方式它是一种线程安全并且是延迟实例化的方式但是因为加锁所以会有性能上的影响。 第二种是通过静态内部类的方式实现它也是一种延迟实例化由于它是静态内部类所以只会使用的时候加载一次不存在线程安全问题。 第三种是通过枚举类的方式实现它既是线程安全的又能防止反序列化导致破坏单例问题 多线程、克隆、反序列化、反射都有可能会造成单例的破坏。而我认为通过枚举的方式实现单例是能够解决所有可能被破坏的情况。