第一次被引用时才会将自己实例化
public class Singleton_Lazy {
private static Singleton_Lazy instance;
private Singleton_Lazy() {};
public static Singleton_Lazy getInstance() {
if (instance == null) {
instance = new Singleton_Lazy();
}
return instance;
}
}
测试
public class Test {
public static void main(String[] args) {
Singleton_Lazy instance1 = Singleton_Lazy.getInstance();
Singleton_Lazy instance2 = Singleton_Lazy.getInstance();
if (instance1 == instance2) {
System.out.println("两个实例是一样的");
System.out.println("实例1地址:" + instance1);
System.out.println("实力2地址:" + instance2);
}
}
}
结果
两个实例是一样的
实例1地址:singletonMode.Singleton_Lazy@4926097b
实力2地址:singletonMode.Singleton_Lazy@4926097b
原理:给代码块儿加锁,最先抢到锁的线程进入代码块创建实例,之后抢到锁的线程也不会创建新的实例
public class Singleton_Lock {
private static Singleton_Lock instance;
private static final Object obj = new Object();
private Singleton_Lock() {};
public static Singleton_Lock getInstance() {
synchronized (obj) {
if (instance == null) {
instance = new Singleton_Lock();
}
return instance;
}
}
}
给代码块加锁,而且锁对象必须是这个类一加载就创建
Double-Check Locking
原理:首先判断有没有实例,没有才会加锁,不用每次都加锁
第二次判空是为了避免前一个拿到锁的线程创建了实例导致第二个拿到锁的线程再次创建实例
public class Singleton_DoubleCheck_Lock {
private static Singleton_DoubleCheck_Lock instance;
private static final Object obj = new Object();
private Singleton_DoubleCheck_Lock() {};
public static Singleton_DoubleCheck_Lock getInstance() {
// 没有实例才加锁
if (instance == null) {
synchronized (obj) {
// 如果两个线程都通过判空校验
// 那么如果前一个线程已经创建了实例 之后进入的线程就不必要创建实例了
if (instance == null) {
instance = new Singleton_DoubleCheck_Lock();
}
}
}
return instance;
}
}
在类加载的时候就实例化对象,所以要提前占用系统资源
public class Singleton_Hungry {
private static final Singleton_Hungry instance = new Singleton_Hungry();
private Singleton_Hungry() {};
public static Singleton_Hungry getInstance() {
return instance;
}
}
因篇幅问题不能全部显示,请点此查看更多更全内容