一、double check+synchronized
优点:懒加载(不用不占空间),正常方式获取的对象全局唯一,线程安全。
缺点:一个线程进入同步块,其余线程只能等待,浪费资源;可以使用反射和序列化破坏单例模式
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* test.LazyDoubleCheckSingleton
* Description:
* date:3/28/2022 1:41 PM
*
* @author:chenweipeng
* @version:1.0
* @since JDK 1.8
*/
public class LazyDoubleCheckSingleton<T> implements Serializable{
//泛型要等到实例化阶段才能被确定,静态变量在类加载过程就已经初始化,加了泛型加载时无法确定类型,所以不能给静态变量加泛型
private volatile static LazyDoubleCheckSingleton instance;
//数据存储
private T data;
private LazyDoubleCheckSingleton(){} //私有化构造器,防止类外使用构造器实例化
public static<T> LazyDoubleCheckSingleton<T> getInstance(Class<T> clazz){ //全局单例获取点
//检查是否要阻塞
if (instance == null){
synchronized (LazyDoubleCheckSingleton.class){
//检查是否要重新创建实例
if (instance == null){
instance = new LazyDoubleCheckSingleton<T>();
}
}
}
return instance;
}
public T getData() {
return data;
}
public LazyDoubleCheckSingleton<T> setData(T data) {
this.data = data;
return this;
}
}
class Test01{
public static void main(String[] args) {
for (int i = 0;i < 100;++i){
int j = i+1;
new Thread(()->{
System.out.println(( "第"+j+"次获取对象的地址"+LazyDoubleCheckSingleton.getInstance(null)));
}).start();
}
}
}
class Test02{
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Constructor<LazyDoubleCheckSingleton> declaredConstructor = LazyDoubleCheckSingleto