================================ ©Copyright 蕃薯耀2022-05-20 https://www.cnblogs.com/fanshuyao/ 一、饿汉模式 public class Hunger { /** * 增加final关键字,避免被修改 */ private static final Hunger hunger = new Hunger();
================================
©Copyright 蕃薯耀 2022-05-20
https://www.cnblogs.com/fanshuyao/
一、饿汉模式
public class Hunger { /** * 增加final关键字,避免被修改 */ private static final Hunger hunger = new Hunger(); /** * 私有化,避免创建对象 */ private Hunger() {}; /** * 提供获取对象的方法 * @return */ public static Hunger get() { return hunger; } }
二、饿汉模式(静态块)
可以通过配置文件对实例进行初始化
import lqy.utils.PropertiesUtils; public class HungerStatic { private static final HungerStatic hungerStatic; private String name; /** * 私有化,避免创建对象 */ private HungerStatic(String name) { this.name = name; }; static { String name = PropertiesUtils.readKeyValue("config.properties", "name"); hungerStatic = new HungerStatic(name); } /** * 提供获取对象的方法 * @return */ public static HungerStatic get() { //System.out.println(hungerStatic); return hungerStatic; } /* @Override public String toString() { return "HungerStatic [name=" + name + "]"; } */ }
三、懒汉模式 - 同步方法
public class LazySafe { private static LazySafe lazySafe; private LazySafe() {} public static synchronized LazySafe get() { if(lazySafe == null) { lazySafe = new LazySafe(); } return lazySafe; } }
四、懒汉模式 - 同步块
public class LazySync { /** * 需要加volatile防止指令重排 */ private static volatile LazySync lazySync; private LazySync() {} public static LazySync get() { synchronized (LazySync.class) { if(lazySync == null) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } lazySync = new LazySync(); } } return lazySync; } }
五、懒汉模式 - 双重判断
public class LazySyncDouble { /** * 需要加volatile防止指令重排 */ private static volatile LazySyncDouble lazySyncDouble; private LazySyncDouble() {} public static LazySyncDouble get() { if(lazySyncDouble == null) { synchronized (LazySyncDouble.class) { if(lazySyncDouble == null) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } lazySyncDouble = new LazySyncDouble(); } } } return lazySyncDouble; } }
六、懒汉模式 - 内部类
/** * Inner是一个内部静态类,当外部类 LazyInner 被加载的时候,并不会创建 Inner实例对象。 * 只有当调用 get() 方法时,Inner才会被加载,这个时候才会创建 instance。 * instance 的唯一性、创建过程的线程安全性,都由 JVM 来保证。 * 所以,这种实现方法既保证了线程安全,又能做到延迟加载。 * @author islee * */ public class LazyInner { private LazyInner() {} /** * 静态内部类 * */ private static class Inner{ private static final LazyInner lazyInner = new LazyInner(); } public static LazyInner get() { return Inner.lazyInner; } }
七、枚举【最安全方式】
最安全,能预防反射和反序列化的安全问题
/** * Java虚拟机会保证枚举类型不能被反射并且构造函数只被执行一次。 * [最安全],其他的会存在反射和反序列化的安全问题 * */ public class SingletonEnum { private SingletonEnum() {} private enum SingletonHolder { INSTANCE; private final SingletonEnum singletonEnum; private SingletonHolder() { singletonEnum = new SingletonEnum(); } private SingletonEnum get() { return singletonEnum; } } public static SingletonEnum get() { return SingletonHolder.INSTANCE.get(); } }
测试:
import lqy.design.singleton.SingletonEnum; public class SingletonEnumTest { public static void singletonEnum() { long startTime = System.currentTimeMillis(); for(int i=0; i<15; i++){ new Thread(()-> { System.out.println(SingletonEnum.get()); }).start(); } long endTime = System.currentTimeMillis(); System.out.println("耗时:" + (endTime - startTime)); } public static void main(String[] args) { singletonEnum(); } }
(时间宝贵,分享不易,捐赠回馈,^_^)
================================
©Copyright 蕃薯耀 2022-05-20
https://www.cnblogs.com/fanshuyao/
今天越懒,明天要做的事越多。