单例模式是一种普遍的设计模式,在任何情况下,都只有一个示例,并且也是单例类自己创建的示例,很多企业在笔试的时候会要求应聘者写单例模式的代码,这其中也把线程安全问题作为考察点,下面是 3 中比较普遍的单例模式:
1. 饿汉模式
public class Singleton
{
private static Singleton singleton=new Singleton(); // 直接初始化一个实例对象
private Singleton(){} // 构造函数私有化,保证其他类对象不能直接new一个该对象的实例
// 获取对象
public static Singleton getSingleton()
{
return singleton;
}
}
上述代码中的一个缺点是该类加载的时候就会直接 new 一个静态对象出来,当系统中这样的类较多时,会使得启动速度变慢 。现在流行的设计都是讲 “延迟加载”,我们可以在第一次使用的时候才初始化第一个该类对象。所以这种适合在小系统。
2. 懒汉模式 (同步代码块)
public class Singleton
{
private static Singleton singleton = null;
private Singleton(){}
// 同步获取对象
public static synchronized Singleton getInstance()
{
if (null == singleton)
{
singleton = new Singleton();
}
return singleton;
}
}
如果不加 synchronized 关键字,就会出现线程安全问题,加了的话,降低了运行效率
3. 懒汉模式 (双重校验锁)
public class Singleton
{
private volatile static Singleton singleton = null;
private Singleton(){}
// 同步获取对象
public static Singleton getInstance()
{
if (null == singleton)
{
synchronized(Singleton.class) // 二次校验
{
if (null == singleton)
{
singleton= new Singleton();
}
}
}
return singleton;
}
}
这里在声明变量时使用了 volatile 关键字来保证其线程间的可见性,在同步代码块中使用二次检查,以保证其不被重复实例化。集合其二者,这种实现方式既保证了其高效性,也保证了其线程安全性。
对于其它类型的单例模式,我就不详细说明了。