在项目开发中,大多数人都会用到单例模式,单线程的常规单例模式写法这里不再赘述,这里只是想对多线程的单例设计模式进行一下描述与分析,提到多线程,大家就会想到线程安全,因此所有人都会想到同步方法,确实应该放到同步方法中进行限制:
下面展示第一种同步方式:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public synchronized static Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
上面所展示的同步方式是将synchronized 关键字放到getInstance()方法上作为修饰符,这种方式确实可以保证线程安全,但是大家有没有想过,为什么要在多线程中保证线程安全,是想对谁进行同步,当然是单例这个对象,大家想一下,如果不进行同步会出现什么情况,就是有可能出现创建多个实例,而非一个唯一实例,因此同步的目的就是要保证对象的唯一性,而当对象已经创建完了之后,我们就不用担心对象不唯一了,因此如果将synchronized 放到方法上就会出现不管是否已经创建好对象,所有线程当调用getInstance方法时都要有先后,这样做是非常影响效率的。
因此正确的方法是:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
看看这种方式是不是特别完美,当已经有单例对象了不用考虑线程安全问题,直接返回单例对象,当,没有创建的时候,进行枷锁同步,在同步代码块里进行二次判断,这样大大的提高了效率。