如果你想精准的控制instance的创建时间,那么就需要使用下面这种方式,一种支持延迟加载的策略,它只会在instance被第一次使用时才会创建对象。代码如下:
/**
* 单例模式之懒汉模式
*
* @author AlanLee
*
*/
public class LazySingleton
{
private static LazySingleton instance = null;
private LazySingleton()
{
System.out.println("LazySingleton is create");
}
public static synchronized LazySingleton getInstance()
{
if (instance == null)
{
instance = new LazySingleton();
}
return instance;
}
}
最初我们并不需要实例化instance对象实例,只有工厂方法getInstance()被第一次调用时才会创建单例对象。但是在高并发环境下,为了防止对象被对此创建,我们不得不使用synchronized进行方法同步。这种实现的好处是,充分利用了延迟加载,只有在真正需要时才创建对象。但坏处也很明显,并发环境下加锁,在锁竞争激烈的时候会对性能产生一定的影响。
此外,还有一种被称为双重检查模式的方法可以用于创建单例。这是一种非常丑陋、复杂的方法,甚至在低版本的JDK中都不能保证正确性。不推荐使用,也没必要在这种方法上花费太多时间。
单例的实现3:
在上述的单例模式实现方式中,可说是各有千秋,那么第三种方式便是结合两者的优势的一种两全其美的实现方式,代码如下:
/**
* 无懈可击之单例模式
*
* @author Alanlee
*
*/
public class StaticSingleton
{
private StaticSingleton()
{
System.out.println("StaticSingleton is create");
}
private static class SingletonHolder
{
private static StaticSingleton instance = new StaticSingleton();
}
public static StaticSingleton getInstance()
{
return SingletonHolder.instance;
}
}
上述代码实现了一个单例模式,并且同时拥有前两种方式的优点。首先工厂方法getInstance()没有使用同步锁,这使得在高并发环境下性能得到了提升。其次,只有在工厂方法getInstance()被第一次调用时,StaticSingleton的实例才会被创建。这种方式巧妙地使用了内部类和类的初始化方式。内部类SingletonHolder被申明为private私有的,这使得我们不可能在外部访问并初始化它。而我们只能在工厂方法getInstance()内部对SingletonHolder类进行初始化,利用虚拟机的类初始化机制创建单例对象。
结束语:宠辱不惊,闲看庭前花开花落;去留无意,漫随天外云卷云舒......小Alan除了喜欢看技术书籍,还是一个武侠玄幻小说爱好者呢!希望自己在IT的这条道路上就能像小说中的主人公一样,纵然困难重重,亦能化险为夷成就康庄大道,至于坐拥美女环抱啥的,小Alan可不敢想啊,还是有一个深爱自己的女人足以。