2.单例模式
饿汉式
在单例模式中,如果存在释放资源的情况下,就不能加final修饰了 public void releaseInstance(){ if(instance != null){ instance = null; } } 释放资源之后,如果需要重新使用这个单例,就必须存在重新初始化的过程,所以不能加final,对于不需要释放资源的情况,可以加final 总而言之,要不要加final修饰,可以根据情况而定
/** * @author wuyimin * @create 2021-07-24 11:31 * @description 饿汉式单例(静态变量方法) * 缺点:在类装载的时候就完成了实例化,没有达到懒加载的效果,如果从未使用过这个实例就会早曾内存的浪费 * 优点:写法简单,在类装载的时候完成了实例化,避免了线程同步的问题 */ public class Hungry { //私有化构造器 private Hungry(){}; //内部创建对象实例(注意修饰符public final static) private final static Hungry instance=new Hungry(); //提供公共的静态方法返回实例对象(方法也必须是静态的) public static Hungry getInstance(){ return instance; } }
/** * @author wuyimin * @create 2021-07-24 11:41 * @description 饿汉式单例(静态代码块的方法) * 优缺点和之前的饿汉式一致 */ public class Hungry2 { //私有化构造器 private Hungry2(){} //不new出来,静态代码块也可以给final常量赋值 private final static Hungry2 instance; //静态代码块加载 static{ instance=new Hungry2(); } //返回单例 public static Hungry2 GetInstance(){ return instance; } }
懒汉式
/** * @author wuyimin * @create 2021-07-24 11:52 * @description 懒汉式单例(线程不安全) * 缺点:线程安全问题,不可以在代码中使用 * 优点:懒加载,节省资源 */ public class Lazy { private Lazy(){}; private static Lazy instance; public static Lazy getInstance(){ if(instance==null){ instance=new Lazy(); } return instance; } }
/** * @author wuyimin * @create 2021-07-24 11:52 * @description 懒汉式单例(线程安全) * 缺点:效率低,实际开发不推荐 * 优点:懒加载,节省资源,解决了线程安全问题 */ public class Lazy { private Lazy(){}; private static Lazy instance; public synchronized static Lazy getInstance(){ if(instance==null){ instance=new Lazy(); } return instance; } }
/** * @author wuyimin * @create 2021-07-24 12:05 * @description 双重检查模式的懒汉式(推荐使用) */ public class LazyDoubleCheck { private LazyDoubleCheck(){} //volatile关键字防止指令重排!!!!!和保证可见性,在一个线程修改一个值的时候,另一个线程可以读到这个修改后的值 private static volatile LazyDoubleCheck instance; public static LazyDoubleCheck getInstance(){ if(instance==null){ synchronized (LazyDoubleCheck.class){ if(instance==null){ instance=new LazyDoubleCheck(); } } } return instance; } }
白给的懒汉式
/** * @author wuyimin * @create 2021-07-24 12:01 * @description 错误的懒汉式,其实没有解决线程安全的问题 * */ public class FailLazy { private FailLazy(){}; private static FailLazy instance; public static FailLazy getInstance(){ if(instance==null){ synchronized (FailLazy.class){ instance=new FailLazy(); } } return instance; } }
静态内部类
/** * @author wuyimin * @create 2021-07-24 12:42 * @description 静态内部类的方法 线程安全,懒加载(静态内部类不会随着subclass的装载而装载)推荐使用 */ public class SubClass { //构造器私有化 private SubClass(){} //静态内部类写入常量 public static class InstanceClass{ private static final SubClass instance=new SubClass(); } //公共接口 public static SubClass getInstance(){ return InstanceClass.instance; } }
枚举方式
/** * @author wuyimin * @create 2021-07-24 12:59 * @description 枚举的单例 */ public enum MyEnum { type1, type2; public void ok(){ System.out.println("hello"); } }