当前位置: 首页 > news >正文

2.设计模式--创建者模式--单例设计模式

2.设计模式–创建者模式–单例设计模式

一个程序整个运行过程中,该实例的对象只被创建一次。

2.1单例设计模式的分类:

饿汉式:类加载时创建单例类的对象
懒汉式:类加载时不创建单例类的对象,第一次访问时创建单例类的对象。

2.2单例设计模式

2.2.1饿汉式(静态变量)

/*** 饿汉式:静态变量创建类的对象*/
public class Singleton {//构造方法私有private Singleton(){}//静态变量创建类的对象private static Singleton instance = new Singleton();//对外提供静态方法public static Singleton getInstance(){return instance;}
}

如果对象不创建会导致内存浪费。

2.2.2 饿汉式(静态代码块)

/*** 饿汉:静态代码块*/
public class Singleton2 {//构造方法私有private Singleton2(){}private static Singleton2 instance;//静态代码块static{instance = new Singleton2();}//对外提供静态对象获取该对象public static Singleton2 getInstance(){return instance;}
}

如果对象不创建会导致内存浪费。

2.2.3 懒汉式(方式一)

/*** 懒汉式*/
public class Singleton3 {/*** 构造方法私有*/private Singleton3(){};//在成员位置创建该类的对象private static Singleton3 instance;/*** 静态获取方法* @return*/public static Singleton3 getInstance(){if(instance==null){instance = new Singleton3();}return instance;}
}

多线程环境,会出现线程安全问题。

2.2.4 懒汉式(方法上synchronized锁)

public class Singleton4 {//私有构造方法private Singleton4(){};//在成员位置创建该类的对象private static Singleton4 instance;/*** 提供静态方法获取变量*/public synchronized static Singleton4 getinstance(){if(instance==null){instance = new Singleton4();}return instance;}
}

在初始化instance的时候才会出现线程安全问题,一旦初始化完成就不存在了。

2.2.4 懒汉式(双重检查锁)

public class Singleton5 {private Singleton5(){};private static Singleton5 instance;public static Singleton5 getInstance(){if(instance==null){//第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实例synchronized (Singleton5.class){//抢到锁之后再次判断是否为nullif(instance==null){instance = new Singleton5();}}}return null;}
}

在多线程的情况下,可能会出现空指针问题,出现问题的原因是JVM在实例化对象的时候会进行优化和指令重排序操作

2.2.5懒汉式(volatile关键字)

public class Singleton6 {private Singleton6(){};//volatile参数存在,不会指令重排序private static volatile Singleton6 instance;public static Singleton6 getInstance(){if(instance==null){//第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实例synchronized (Singleton6.class){//抢到锁之后再次判断是否为nullif(instance==null){instance = new Singleton6();}}}return null;}
}

2.2.6懒汉式(静态内部类方式)

public class Singleton7 {//私有方法构造private Singleton7(){};private static class singletonHolder{private static final Singleton7 INSTANCE = new Singleton7();}public static Singleton7 getInstance(){return singletonHolder.INSTANCE;}
}

静态属性由于被 static修饰,保证只被实例化一次,并且严格保证实例化顺序

3.1破坏单例模式

1.序列化和反序列化

public class SingletonDemo {public static void main(String[] args) throws Exception {//往文件中写对象writeObject2File();//从文件中读取对象Singleton s1 = readObjectFromFile();Singleton s2 = readObjectFromFile();//判断两个反序列化后的对象是否是同一个对象System.out.println(s1 == s2);}private static Singleton readObjectFromFile() throws Exception {//创建对象输入流对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\a.txt"));//第一个读取Singleton对象Singleton instance = (Singleton) ois.readObject();return instance;}public static void writeObject2File() throws Exception {//获取Singleton类的对象Singleton instance = Singleton.getInstance();//创建对象输出流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\a.txt"));//将instance对象写出到文件中oos.writeObject(instance);}
}

2.反射

public class Test {public static void main(String[] args) throws Exception {//获取Singleton类的字节码对象Class clazz = Singleton.class;//获取Singleton类的私有无参构造方法对象Constructor constructor = clazz.getDeclaredConstructor();//取消访问检查constructor.setAccessible(true);//创建Singleton类的对象s1Singleton s1 = (Singleton) constructor.newInstance();//创建Singleton类的对象s2Singleton s2 = (Singleton) constructor.newInstance();//判断通过反射创建的两个Singleton对象是否是同一个对象System.out.println(s1 == s2);}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • docker 容器内部UI映射host
  • STM32智能工业自动化监控系统教程
  • 科普文:详解23种设计模式
  • 代码随想录——分割等和子集(Leetcode LCR 101)
  • 【STC89C51单片机】定时器/计数器的理解
  • Lianwei 安全周报|2024.07.15
  • LLM 构建Data Multi-Agents 赋能数据分析平台的实践之④:数据分析之三(数据展示)
  • Jenkins 安装、部署与配置
  • JVM:自动垃圾回收
  • flutter ios打包 xcode报错module ‘xxx‘ not found
  • Python爬虫入门篇学习记录
  • 使用Nginx实现高效负载均衡
  • 零基础STM32单片机编程入门(十五) DHT11温湿度传感器模块实战含源码
  • Guava LocalCache源码分析:LocalCache生成
  • 在组件中显示tuku的照片
  • 【Leetcode】101. 对称二叉树
  • 2017届校招提前批面试回顾
  • ES6--对象的扩展
  • Flannel解读
  • iOS 颜色设置看我就够了
  • Java 多线程编程之:notify 和 wait 用法
  • Java 网络编程(2):UDP 的使用
  • laravel5.5 视图共享数据
  • oldjun 检测网站的经验
  • php面试题 汇集2
  • react 代码优化(一) ——事件处理
  • Spark RDD学习: aggregate函数
  • SpiderData 2019年2月16日 DApp数据排行榜
  • SwizzleMethod 黑魔法
  • vue--为什么data属性必须是一个函数
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 如何实现 font-size 的响应式
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • - 转 Ext2.0 form使用实例
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • ​​​​​​​STM32通过SPI硬件读写W25Q64
  • ​【数据结构与算法】冒泡排序:简单易懂的排序算法解析
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (十二)Flink Table API
  • (四) Graphivz 颜色选择
  • (译) 函数式 JS #1:简介
  • (自用)网络编程
  • ***监测系统的构建(chkrootkit )
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .NET 中的轻量级线程安全
  • .NET分布式缓存Memcached从入门到实战
  • .net生成的类,跨工程调用显示注释
  • @antv/g6 业务场景:流程图
  • [ Linux ] Linux信号概述 信号的产生
  • [16/N]论得趣
  • [22]. 括号生成
  • [BJDCTF2020]The mystery of ip1