单例模式,即保证某个类只有一个实例,网上有很多构造单例的方法,或多或少有其缺陷。如DCL(double check lock)模式,不能保证对象能被正确发布。
使用静态变量
public class CarFactory { private static CarFactory instance = new CarFactory(); private CarFactory(){ } public static CarFactory getInstance(){ return instance; } }
这个能保证安全性,但是在不需要引用对象的instance时,对象也可能被创建,会造成资源浪费
Double Check Lock(DCL)
public class CarFactory { private static CarFactory instance = null; private CarFactory(){ } public static CarFactory getInstance(){ if(instance == null){ synchronized (CarFactory.class){ if(instance == null){ instance = new CarFactory(); } } } return instance; } }
这个是网上流传的非常广泛的单例模式构造方法,据说既能保证安全性,又能按需创建。但是仔细想想,在线程A和线程B同时调用getInstance()方法时,线程A调用了instance = new CarFactory(),但是对象还没有初始化完毕,这时instance已经不为null,而线程B会认为instance不为null,直接使用instance。这就会造成引用逸出,根据JMM,线程A中初始的数据对线程B的可见性没法保证。这可能会产生很严重的后果
线程安全&&按需创建
public class CarFactory { private CarFactory(){ } public static class SingleInstance{ static CarFactory instance = new CarFactory(); } public static CarFactory getInstance(){ return SingleInstance.instance; } }
只有在调用getInstance()方法时,才能创建CarFactory实例,而且保证了线程安全性。
时间: 2024-10-28 11:11:50