饿汉模式
在类创建的时候就实例化对象
class SingleTon {
private static SingleTon instance = new SingleTon();
private SingleTon() {
}
public static SingleTon getInstance() {
return instance;
}
}
懒汉模式
只有在第一次使用的时候才会实例化对象
class LazySingleTon {
private static LazySingleTon instance = null;
private LazySingleTon() { }
public static LazySingleTon getInstance() {
if (instance == null) {
instance = new LazySingleTon();
}
return instance;
}
}
上面的懒汉模式代码在单线程的情况下是安全的, 但是在多线程的情况下是线程不安全的
线程安全问题发生在首次创建实例时. 如果在多个线程中同时调用 getInstance 方法, 就可能导致
创建出多个实例.可以通过加锁来实现线程安全
class LazySingleTon {
private static LazySingleTon instance = null;
private LazySingleTon() { }
public static synchronized LazySingleTon getInstance() {
if (instance == null) {
instance = new LazySingleTon();
}
return instance;
}
}
但是, 上锁和解锁是非常占用系统资源的, 而且只有在第一次使用的时候才会加锁, 所以可以改进一下
class LazySingleTon {
private static volatile LazySingleTon instance = null;
private LazySingleTon() { }
public static LazySingleTon getInstance() {
if (instance == null) {
synchronized (LazySingleTon.class) {
if (instance == null) {
instance = new LazySingleTon();
}
}
}
return instance;
}
}
此时只有在第一次使用的时候才会加锁, 减小了系统资源的浪费, 加volatile是为了防止在创建对象的时候发生指令重排序.