💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
**方案1** 类初始化时创建,缺点是如果类过多或初始化程序耗时,启动时间较长;过早创建实例,降低内存使用效率。 ``` class Solution { private Solution(){} private static Solution instance = new Solution(); /** * @return: The same instance of this class every time */ public static Solution getInstance() { return instance; } }; ``` **方案2** 延迟初始化,缺点是多线程时,如果同时判断instance为null,可能会创建多个实例。 ``` class Solution { private Solution(){} private static Solution instance = null; /** * @return: The same instance of this class every time */ public static Solution getInstance() { if(instance == null){ instance = new Solution(); } return instance; } }; ``` **方案3** 多线程,为方法加锁synchronized,缺点是如果同时有多个方法调用会依次进入,性能较低 ``` class Solution { private Solution(){} private static Solution instance = null; /** * @return: The same instance of this class every time */ public static synchronized Solution getInstance() { if(instance == null){ instance = new Solution(); } return instance; } }; ``` **方案4** 只有在instance未初始化时,多个线程在初始化之前会加锁,instance不为null时不会加锁;缺点是如果多个线程在`synchronized(Solution.class)`上等待时,如果第一个线程初始化释放锁后,第二个线程池进入还是会再次创建。 ``` class Solution { private Solution(){} private static Solution instance = null; /** * @return: The same instance of this class every time */ public static Solution getInstance() { if(instance == null){ synchronized(Solution.class){ instance = new Solution(); } } return instance; } }; ``` **方案5** 在方案4的基础上,如果第一个线程初始化释放锁后,其他线程池进入先判断instance是否为null,如果不为null则不创建。 ``` class Solution { private Solution(){} private static Solution instance = null; /** * @return: The same instance of this class every time */ public static Solution getInstance() { if(instance == null){ synchronized(Solution.class){ if(instance == null){ instance = new Solution(); } } } return instance; } }; ``` **方案6** 由于重排序的问题, 对象的初始化分为3步,但是重排序时会先赋值后初始化 ``` memory = allocate(); //1.分配内存空间 ctorInstance(memory); //2.初始化对象 instance = memory; //3.设置instance执行分配的地址 //由于重排序,执行时序如下: memory = allocate(); //1.分配内存空间 instance = memory; //2.设置instance执行分配的地址 ctorInstance(memory); //3.初始化对象 ``` 这会导致线程1在第2步后赋值,然后线程2进入看到不为null就返回了,此时指针对应的内存还未初始化。因此需要加入volatile ``` private static volatile Solution instance = null; ``` **方案6** 我们需要的是延迟加载,并且只有一个线程初始化,因此可以考虑内部类,内部类在使用时才会初始化。 ``` class Solution { public static Solution getInstance() { return Solution.InnerClass.getInstance(); } private static class InnerClass{ private static Solution instance = new Solution(); public static Solution getInstance(){ return instance; } } }; ``` > 要点 * 构造函数是私有的 * 不要初始化时创建,要延迟创建;过早创建会降低内存使用效率