单件模式(Singleton Pattern):用来创建独一无二的,只能有一个实例的对象的入场券。
经典的一个单件
public class Singleton{
private static Singleton uniqueInstance;
private Singleton(){}
public static Singleton getInstance(){
if(uniqueInstance==null)
{
uniqueInstance=new Singleton();
}
return uniqueInstance;
}
}
单件模式:确保一个类只有一个实例,并提供一个全局访问点。
getInstance()方法时静态的,这意味着它是一个类方法,所以可以在代码的任何地方使用Singleton.getInstance()访问它。这和访问全局变量一样简单,只是多了一个优点:单件可以延迟实例化。
对待getInstance()方法,我们要处理多线程情况。
只要把getInstance()变成同步(synchronized)方法,多线程灾难几乎可以轻易解决多线程问题。
public static synchronized Singleton getInstance(){...},这种做法的特点是:我们迫使每个线程在进入这个方法之前,要先等候别的线程离开该方法。也就是所两个线程不会同时进入这个方法。
改善多线程的方法:
1.如果getInstance()的性能对应用程序不是很关键,就什么也别做,就按照上面的做法使用。
2.使用“急切”创建实例,而不用延迟实例化的做法,也就是全局变量的意思。
public class Singleton{
private static Singleton uniqueInstance=new Singleton();
private Singleton(){}
public static Singleton getInstance(){return uniueInstance;}
}
3.用“双重检查加锁”,在getInstance()中减少使用同步
利用双重检查加锁(double-checked locking),首先检查是否实例化已经创建了,如果尚未创建,“才”进行同步。这样一来,只有第一次会同步,这正是我们想要的。
public class Singleton{
private volatile static Singleton uniueInstance;
private Singleton(){}
public static Singleton getInstance()
{
if(uniqueInstance==null)
{
synchronized(Singleton.class)
{
if(uniqueInstance==null)
{
uniqueInstance=new Singleton();
}
}
}
return uniqueInstance;
}
}
volatile关键字确保,当uniqueInstance变量被初始化成Singleton实例时,多个线程正确处理uniueInstance变量。