一、“ 饿汉 ” 模式
在类加载的时候就立即实例化对象
// “饿汉”模式-------线程安全
static class Singleton {
// 私有的构造方法,外部类不可以 new 实例,但是因为此类是 ThreadDemo11 的内部类,可以 new
private Singleton() { }
public static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
” 饿汉 “ 模式,因为只有读数据操作,线程安全
二、“ 懒汉 ” 模式
只在首次调用 getInstance 时才实例化对象
// “懒汉模式”-------对于实例创建好之前,线程不安全
static class Singleton {
private Singleton() {}
private static Singleton instance = null;
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
“ 懒汉 ” 模式效率较高于 “ 饿汉 ” 模式
但是 “ 懒汉 ”模式在实例化之前涉及多线程修改,是不安全的,但是在实例化之后,就安全了
为了保证线程安全,进行以下操作
1、加锁,来保证判断和实例化是原子的
2.、双重 if,来避免实例化以后,再调用 getInstance 时频繁触发不必要的锁操作
3、volatile 来保证内存可见性
// 等到第一次使用这个实例时再实例化,效率较高(有锁后,效率就低了)
static class Singleton {
private Singleton() {}
//类加载时没有实例化,第一次调用时才实例化 ,相当于“延时加载”
// private static Singleton instance = null;
// 为了保证内存可见,在 instance 前加 volatile
private volatile static Singleton instance = null;
public static Singleton getInstance() {
// 只在第一步实例化的加锁,提高效率
if (instance == null) {
// 加锁,来保证线程安全
synchronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}