Singleton Pattern
有一些对象我们只需要一个,比如线程池,数据库连接池,注册表。。。当然,依靠程序员口头约定和全局变量也可以实现单例,但单例模式是更好的办法
接下来,我们实现一个经典的单例模式
public class Singleton
{
public static Singleton single;//提供只能被实例化一次的全局变量
private Singleton(){} //私有化构造函数
public static Singleton getInstance()
{
if(single == null)
{
single = new Singleton();
}
return single;
}
}
但是,当程序进行多线程优化时,两个线程同时第一次获取单例时,此时single为空,会返回两个实例,下面我们处理多线程单例
第一种方法:添加synchronized,每个线程在访问该方法前会先等候其他线程离开
class Singleton {
private static Singleton instantce;
private Singleton() {}
public static synchronized Singleton getInstantce() {
if (instantce == null) {
instantce = new Singleton();
}
return instantce;
}
}
但只有第一次执行此方法时,才需要同步,之后每次调用都会损耗性能
第二种方法:“急切”创建实例
class Singleton {
private static Singleton instantce = new Singleton();
private Singleton() {}
public static synchronized Singleton getInstantce() {
return instantce;
}
}
第三种方法:双重检查加锁
class Singleton {
private static volatile Singleton instantce;
private Singleton() {}
public static synchronized Singleton getInstantce() {
if (instantce == null) {
synchronized (Singleton.class) {
if (instantce == null) {
instantce = new Singleton();
}
}
}
return instantce;
}
}
双重检查加锁,首先检查shingle是否为空,如果为空,才进行同步,这正是我们想要的