欧美网站模板拿p5.js做的网站

当前位置: 首页 > news >正文

欧美网站模板,拿p5.js做的网站,网站建设 长安,把网站提交谷歌文章目录 单例模式1️⃣特性#x1f4aa;单例模式的类型与实现#xff1a;类型懒汉式实现(线程不安全)懒汉式实现(线程安全#xff09;双重锁校验懒汉式(线程安全)饿汉式实现(线程安全)使用类的内部类实现⭐枚举方式实现单例#xff08;推荐#xff09;#x1f44d; 单例… 文章目录 单例模式1️⃣特性单例模式的类型与实现类型懒汉式实现(线程不安全)懒汉式实现(线程安全双重锁校验懒汉式(线程安全)饿汉式实现(线程安全)使用类的内部类实现⭐枚举方式实现单例推荐 单例模式1️⃣ 单例模式是指在内存中只会创建且仅创建一次对象的设计模式。让你能够保证一个类只有一个实例 并提供一个访问该实例的全局节点。 特性 唯一性整个系统中单例类只能有一个实例。私有化构造函数防止外部通过new关键字直接创建对象。静态方法提供全局访问点通常使用getInstance()方法来获取该类的唯一实例。延迟实例化懒加载有些实现会在第一次调用getInstance()时才创建实例以节省资源。 单例模式的类型与实现 类型 懒汉式在真正需要使用对象时才去创建该单例类对象饿汉式在类加载时已经创建好该单例对象等待被程序使用 懒汉式实现(线程不安全) 只有当调用getInstance()方法时才会创建单例对象这种方式实现了延迟加载但是需要考虑多线程环境下的线程安全问题。 public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance null) {instance new Singleton();}return instance;} }单例模式不允许外部直接创建所以构造函数添加私有属性private这种方式满足懒汉式但是在并发场景下多个线程使用单例对象可能导致实例并存从而违反了单例要求 懒汉式实现(线程安全 上述懒汉式实现是线程不安全的例如同时两个线程去获取单例对象如果此时单例对象还未创建可能会导致同事创建两个对象从而违反单例故我们要解决线程安全问题。 最容易想到的方法使用锁(synchronized)给类加锁来保证线程安全 public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance null) {instance new Singleton();}return instance;} }双重锁校验懒汉式(线程安全) 但是上述方法每次获取对象的时候都要去先获取锁并发性能不是很好 可以进行优化(如果没有实例化则加锁创建如果实例化了则直接获取可以使得已经实例化的单例对象在获取单例对象时无需先获取锁而是直接获取对象) 使用Double Check双重校验 Lock加锁 的写法 public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance null) { // 第一次检查为了避免不必要的同步操作提高性能。synchronized(Singleton.class) { if (instance null) { // 第二次检查以确保即使在多线程环境下也只创建一个实例。instance new Singleton();}}}return instance;} }同时我们也使用了volatile关键字去确保instance变量的更新对所有线程都是立即可见的并且禁止指令重排序保证多线程环境下的正确性。 防止指令重排序 在多线程环境下JVM为了优化性能可能会对指令进行重排序。对于单例对象的创建而言构造函数内部的操作可能被重排序到对象引用赋值之后。例如如果一个线程正在执行实例化操作它可能会先将对象引用设置为非空即指向一块内存然后再完成对象的初始化。这种情况下另一个线程可能看到的是一个部分初始化的对象因为对象的引用不是null了这会导致不可预测的行为或错误。volatile关键字可以禁止这种指令重排序保证对象完全初始化之后才会被其他线程看到。可见性保证 volatile关键字确保了一个线程对共享变量在这个场景下是单例对象的引用的修改对于其他线程是立即可见的。也就是说当一个线程成功创建了单例对象后所有其他线程都能看到这个对象已经被正确地初始化了而不会读取到旧的或者默认的值如null。这避免了多个线程同时创建多个实例的情况。 饿汉式实现(线程安全) 在类加载的时候就创建好单例对象这种方式简单但不够灵活因为它不能做到延迟加载。 public class Singleton{private static final Singleton singleton new Singleton();private Singleton(){}public static Singleton getInstance() {return singleton;} }在类加载的时候private static final Singleton singleton new Singleton();这行代码已经实例化好了一个单例对象在内存中。 使用类的内部类实现⭐ 利用了Java语言的类加载机制只有当调用getInstance()方法时内部类才会被加载从而实现了懒加载和线程安全同时不会因为加锁的方式耗费性能。 public class Singleton {private Singleton() {}private static class SingletonHolder {private static final Singleton INSTANCE new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;} }这主要是因为JVM虚拟机可以保证多线程并发访问的正确性也就是一个类的构造方法在多线程环境下可以被正确的加载。此种方式也是非常推荐使用的一种单例模式 枚举方式实现单例推荐 在Java中使用枚举Enum来实现单例模式是一种非常简洁且高效的方法。枚举类型的单例不仅能够防止反射攻击和序列化导致的重复实例化问题而且代码量极少易于理解和维护。这是因为Java的枚举机制保证了每个枚举常量的唯一性并且在类加载时自动初始化。 public enum Singleton {INSTANCE;private final String property;// 初始化属性值Singleton() {this.property Some Value;}public String getProperty() {return property;}// 其他业务方法public void doSomething() {// 方法逻辑…} }public class Client {public static void main(String[] args) {Singleton singleton Singleton.INSTANCE;singleton.doSomething();System.out.println(singleton.getProperty());} }枚举单例的优点 天然线程安全由于枚举常量在类加载时就被初始化所以不需要额外的同步代码来保证线程安全。防止反序列化创建新实例枚举类型具有内在的序列化机制如果尝试反序列化一个枚举类型的对象它总是返回现有的枚举常量而不会创建新的实例。防止反射攻击即使通过反射调用私有构造函数也无法创建新的枚举实例。简洁相比于其他单例模式的实现方式枚举单例的代码更加简洁明了。延迟加载虽然枚举类型不是天生支持懒加载但是可以通过将实际的工作委托给另一个静态内部类来实现这一点。