1.延迟实例化
当我们不急切需要一个实例时,也就是当用户需要一个实例时,再创建实例。
a.同步低效率版
public class Singleton { private static Singleton uniqueInstance; //私有化构造方法,防止用户通过构造器构造 private Singleton(){} //同步方法,同一时间,只允许一个用户调用该方法获取实例 public static synchronized Singleton getInstance(){ if (uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } }这种写法虽然简单,但是效率低下,实际上同步只需要在实例未创建完成时起作用就可以,防止多线程使得多个用户得到不同的实例。而已经有了一个实例的时候,同步就不需要了。如果你不关心效率,就可以用该方法,简单清晰。b.双重检查加锁
public class Singleton { //volatile关键词确保:档uniqueInstance变量被初始化成Singleton实例时,多个线程正确的处理uniqueInstance变量 private volatile static Singleton uniqueInstance; //私有化构造方法,防止用户通过构造器构造 private Singleton(){} public static Singleton getInstance(){ if (uniqueInstance == null){//检查实例,如果不存在就进入同步区块,只有第一次才彻底执行这里的代码 synchronized (Singleton.class){ if (uniqueInstance == null){//进入区块后,再检查一次,如果仍是null,才创建实例。 uniqueInstance = new Singleton(); } } } return uniqueInstance; } }2.急切实例化
在静态初始化中创建单价,保证了线程安全,用户需要用时,实例已经生成好。
public class Singleton { private volatile static Singleton uniqueInstance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return uniqueInstance; } }
