郭卫东 发表于 2024-8-25 03:56:34

JAVA设计模式之【单例模式】

https://img-blog.csdnimg.cn/img_convert/ed5a1a778dfc2c4f5b5ebaaa03480a31.png
1 类图

https://img-blog.csdnimg.cn/img_convert/2c2ac383fce5c04b703e90bb9bbedcea.png
2 饿汉式单例

比方:静态块、静态成员
2.1 概念

类加载的时候就立即初始化,而且创建单例对象
2.2 长处

没有加任何的锁、实验效率比力高
2.3 缺点

类加载的时候就初始化,不管用与不用都占着空间,浪费了内存。
3 懒汉式单例

3.1 直接:线程不安全

public class LazySimpleSingleton {
    private LazySimpleSingleton(){}
    //静态块,公共内存区域
    private static LazySimpleSingleton lazy = null;
    publicstatic LazySimpleSingleton getInstance(){
      if(lazy == null){
            lazy = new LazySimpleSingleton();
      }
      return lazy;
    }
}
3.2 同步方法

public class LazySimpleSingleton {
    private LazySimpleSingleton(){}
    //静态块,公共内存区域
    private static LazySimpleSingleton lazy = null;
    public synchronized static LazySimpleSingleton getInstance(){
      if(lazy == null){
            lazy = new LazySimpleSingleton();
      }
      return lazy;
    }
}
3.2.1 优化CPU:双重检查锁

public class LazyDoubleCheckSingleton {
    private volatile static LazyDoubleCheckSingleton lazy = null;
    private LazyDoubleCheckSingleton(){}
    public static LazyDoubleCheckSingleton getInstance(){
      if(lazy == null){
            synchronized (LazyDoubleCheckSingleton.class){
                if(lazy == null){
                  lazy = new LazyDoubleCheckSingleton();
                  //1.分配内存给这个对象
                  //2.初始化对象
                  //3.设置lazy指向刚分配的内存地址
                  //4.初次访问对象
                }
            }
      }
      return lazy;
    }
}
3.2.2IDEA 情况下的多线程调试

3.3 静态内部类

这种形式兼顾饿汉式的内存浪费,也兼顾synchronized性能题目,完美地屏蔽了这两个缺点
//史上最牛B的单例模式的实现方式
public class LazyInnerClassSingleton {
    //默认使用LazyInnerClassGeneral的时候,会先初始化内部类
    //如果没使用的话,内部类是不加载的
    private LazyInnerClassSingleton(){
      if(LazyHolder.LAZY != null){
            throw new RuntimeException("不允许创建多个实例");
      }
    }
    //每一个关键字都不是多余的
    //static 是为了使单例的空间共享
    //保证这个方法不会被重写,重载
    public static final LazyInnerClassSingleton getInstance(){
      //在返回结果以前,一定会先加载内部类
      return LazyHolder.LAZY;
    }
    //默认不加载
    private static class LazyHolder{
      private static final LazyInnerClassSingleton LAZY = new LazyInnerClassSingleton();
    }
}
3.3.1 反射粉碎单例

在构造函数上抛出异常
    private LazyInnerClassSingleton(){
      if(LazyHolder.LAZY != null){
            throw new RuntimeException("不允许创建多个实例");
      }
    }
3.3.2 序列化粉碎单例

增加 readResolve()方法
public class SeriableSingleton implements Serializable {
    publicfinal static SeriableSingleton INSTANCE = new SeriableSingleton();
    private SeriableSingleton(){}
    public static SeriableSingleton getInstance(){
      return INSTANCE;
    }
    privateObject readResolve(){
      returnINSTANCE;
    }
}
4 注册式单例

4.1 罗列式单例

利用jdk特性。具有线程安全、实例唯一(杜绝反序列化破坏单例)的特点。
public enum EnumSingleton {
    INSTANCE;
    private Object data;
    public Object getData() {
      return data;
    }
    public void setData(Object data) {
      this.data = data;
    }
    public static EnumSingleton getInstance(){
      return INSTANCE;
    }
}
4.1.1 长处

线程安全、实例唯一
4.2 容器缓存写法

public class ContainerSingleton {
    private ContainerSingleton(){}
    private static Map<String,Object> ioc = new ConcurrentHashMap<String,Object>();
    public static Object getInstance(String className){
      synchronized (ioc) {
            if (!ioc.containsKey(className)) {
                Object obj = null;
                try {
                  obj = Class.forName(className).newInstance();
                  ioc.put(className, obj);
                } catch (Exception e) {
                  e.printStackTrace();
                }
                return obj;
            } else {
                return ioc.get(className);
            }
      }
    }
}
4.2.1 长处

对象方便管理、懒加载
4.2.2 缺点

不加上synchronized存在线程安全题目
5 ThreadLocal-线程单例

5.1 写法

public class ThreadLocalSingleton {
    private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance =
            new ThreadLocal<ThreadLocalSingleton>(){
                @Override
                protected ThreadLocalSingleton initialValue() {
                  return new ThreadLocalSingleton();
                }
            };
    private ThreadLocalSingleton(){}
    public static ThreadLocalSingleton getInstance(){
      return threadLocalInstance.get();
    }
}
5.2 长处

保证在单个线程中是唯一

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: JAVA设计模式之【单例模式】