1 最原始的实现单例模式的方法(存在线程不安全):
public class SingletonOne {
private static SingletonOne instance = null;
private SingletonOne() {}
public static SingletonOne getInstance() {
if (instance == null) {
instance = new SingletonOne();
}
return instance;
}
}
但是这种方法有一个弊端,就是存在线程的不安全!
比如当两个线程同时进入if(instance == null)时,一个线程判断了当前为空,然后切换到另一个线程,这个线程也判断为空。然后切换回第一个线程,进行实例化,再切换到第二个线程,进行实例化。这样就存在了两个实例。
2 通过关键字Synchronized强制线程同步
public class SingletonTwo {
private static SingletonTwo instance = null;
private SingletonTwo() {}
public static synchronized SingletonTwo getInstance() {
if (instance == null) {
instance = new SingletonTwo();
}
return instance;
}
}
这样当线程进行到getInstance会同步的进行,不会有线程安全问题,但是不仅仅是实例化,每次调用也需要同步,这样就会造成很多资源的浪费。
3 通过静态内部类进行单例
public class SingletonThree {
private static class SingletonHolder{
static SingletonThree instance = new SingletonThree();
}
private SingletonThree() {}
public static SingletonThree getInstance() {
return SingletonHolder.instance;
}
}
这种方法是比较推荐的一种方法,由于Java的调用机制,SingletonHolder只有在调用getInstance的时候才会加载,而内部的静态类只会被加载一次,因此又是线程安全的。
4 通过枚举进行单例
public class SingletonFour {
}
public enum SingletonHolder {
INSTANCE;
private SingletonFour instance;
SingletonHoler() {
instance = new SingletonFour();
}
public SingletonFour getInstance() {
return instance;
}
}
这种方法是最推荐的一种方法
总结起来
:
第一种方法,是存在线程安全问题的。
第二种方法,则消耗了一定的资源。
第三种方法,比较推荐。