怎么从建设部网站下载规范,wordpress同时上传多个文件,seo综合查询使用vsping工具,晋城网站建设1.单例模式概念#xff1a; 单例模式是一种设计模式#xff0c;他的核心是确保一个类只有一个实例#xff0c;单例模式主要有两种方式#xff1a;饿汉式与懒汉式 2.饿汉式
饿汉就是一个迫切的意思#xff0c;类加载就会导致该单实例被创建
饿汉式第一种方式#xff1a;…1.单例模式概念 单例模式是一种设计模式他的核心是确保一个类只有一个实例单例模式主要有两种方式饿汉式与懒汉式 2.饿汉式
饿汉就是一个迫切的意思类加载就会导致该单实例被创建
饿汉式第一种方式
class Singleton{//在本类中创建本类对象private static Singleton instancenew Singleton();//提供一个公共的访问方式让外界获取该对象public static Singleton getInstance(){return instance;}//私有构造方法private Singleton() {}
}
我们来对上面这个饿汉式解析一下 1.私有构造方法对于构造方法我们使用private修饰那么就保证了外界不能通过new这个操作来获取实例 2.饿汉我们在类里面new一个实例这个成员变量用private修饰外界是无法获取的同时static修饰了他我们知道静态成员的初始化是在类加载的阶段触发的所以只要这个类一被加载那么我们的实例也就创建好了 3.getInstance方法同样也是static修饰的这是因为在本类中创建的实例是被static修饰的普通的方法不能直接去访问所以要将获取对象的这个方法也用static修饰Singleton这个类不能构建实例我们要想获取实例就只能类名.getInstance来获取到实例然后通过这个实例去调用其他的方法或成员变量 饿汉式第二种方式
class Singleton2{private static Singleton2 instance ;static {instancenew Singleton2();
}//对外提供方法获取该对象
public static Singleton2 getInstance(){return instance;
}//私有化的构造方法private Singleton2() {}
} 这种方式和第一种类似只不过在本类当中创建对象的方式变成了使用静态代码块来创建 饿汉式第三种方式枚举方式
public enum Singleton3{instance;
} 枚举方式实现单例模式是极力推荐的单例实现模式因为枚举类型是线程安全的并且只会装载一次枚举实现的单例模式是唯一一种不会被破坏的单例实现模式 饿汉式总结说明
这种方式在成员位置声明Singlleton类型的静态变量并创建Singleton类的对象instance。instance对象会随着类的加载而创建。如果对象足够大1的话而一直没有使用就会造成内存的浪费 2.懒汉式
类加载不会导致该单实例对象被创建而是首次使用才会被创建 懒汉式第一种方式线程不安全的
class Singleton3{
//声明成员变量不进行初始化private static Singleton3 instance;//提供获取对象的方法public static Singleton3 getInstance(){if(instancenull){instancenew Singleton3();}return instance;}//私有化的构造方法private Singleton3() {}
} 1.私有化的构造方法是为了不让外界通过new创建多个实例 2.声明Singleton3类的成员变量不进行初始化 3.由于懒汉式是当我们用到时才去创建对象所以在调用getinstance方法时才去创建 4.单列模式是一个类只能创建一个对象供外界使用所以在调用getinstance方法时getinstance方法内要做一次判断判断一下instance这个变量是否为空为空则创建这个实例不为空则直接return 5.上面这种写法之所以线程不安全是因为在多线程中如果线程1调用getinstance这个方法执行到if语句然后被操作系统调度到线程2线程2也执行getinstance这个方法线程2执行完毕后又调度到线程1的if语句这时执行new的操作此时线程1和线程2都单独创建了一个SIngleton3的对象这时就不满足单例模式只能创建一个对象的原则所以就是线程不安全的 懒汉式第二种方式线程安全的
class Singleton3{private static Singleton3 instance;public static synchronized Singleton3 getInstance(){if(instancenull){instancenew Singleton3();}return instance;}private Singleton3() {}
} 懒汉式线程安全的只需要在getinstance方法加上synchronized修饰就行了这是给这个方法加上锁锁对象是this这样就保证了当一个线程执行getinstance方法时不会被其他线程调度走 懒汉式第三种方式双重检查锁 为什么要使用双重检查锁对于上述的两种懒汉式来说getinstance方法大多数都是在进行读操作而我们说多线程里面读操作是线程安全的而写操作是线程不安全的写操作只有new 对象赋值给instance我们没必要让每个线程必须持有锁才能调用该方法我们需要调整加锁的时机来提高性能 class Singleton3{private static Singleton3 instance;public static synchronized Singleton3 getInstance(){if(instancenull){synchronized (Singleton3.class){if(instancenull){instancenew Singleton3();}}}return instance;}private Singleton3() {}
} 1.双重锁模式只是在前面两种方式的基础上将getinstance方法就行了修改首先对instance进行判断如果instance对象为空那么就进行抢占锁操作抢到锁之后在进行一次判断如果为空就进行new对象如果第一次判断instance不为空那么说明instance已经创建直接返回这个对象就行了 对双重检查锁的优化 在多线程的情况下双重检查锁可能会出现空指针问题出现问题的原因是JVM在实例化对象的时候会进行优化和指令重排序操作要解决双重检查锁模式带来空指针异常的问题只需要使用volatile关键字volatile关键字可以保证可见性和有序性 class Singleton3{private static volatile Singleton3 instance;public static synchronized Singleton3 getInstance(){if(instancenull){synchronized (Singleton3.class){if(instancenull){instancenew Singleton3();}}}return instance;}private Singleton3() {}
}
添加volatile关键字之后能够保证多线情况下的线程安全也不会有性能问题 懒汉式第四种方式静态内部类 静态内部类单例模式中实例有内部类创建由于JVM在加载外部类的过程中是不会加载静态内部类的只有内部类的属性/方法被调用时才会被加载并初始化其静态属性。静态属性由于被static修饰保证只被实例化一次并且严格保证实例化顺序 class Singleton4{
private static class SingletonHolder{
private final static Singleton4 INSTANCEnew Singleton4();
}public static Singleton4 getInstance(){return SingletonHolder.INSTANCE;
}private Singleton4() {}
} 说明 第一次加载SIngleton4类时不会去初始化INSTANCE只有第一次调用getinstance虚拟机加载SingletonHolde并初始化INSTANCE这样不仅能保证线程安全也能保证Singleton类的唯一性 静态内部类的方式在没有加锁的情况下保证了线程安全有没有影响性能和空间的浪费