首页
统计
关于
Search
1
Sealos3.0离线部署K8s集群
1,085 阅读
2
类的加载
742 阅读
3
Spring Cloud OAuth2.0
726 阅读
4
SpringBoot自动装配原理
691 阅读
5
集合不安全问题
586 阅读
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
FastApi
登录
Search
标签搜索
Java
CSS
mysql
RabbitMQ
JavaScript
Redis
JVM
Mybatis-Plus
Camunda
多线程
CSS3
Python
Spring Cloud
注解和反射
Activiti
工作流
SpringBoot
Mybatis
Spring
html5
蘇阿細
累计撰写
389
篇文章
累计收到
4
条评论
首页
栏目
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
FastApi
页面
统计
关于
搜索到
1
篇与
的结果
2022-08-27
创建者模式-单例模式
特点:将对象的创建与使用分离,可以降低系统的耦合度,使用者不需要关注对象的创建细节分为:单例模式、工厂模式、抽象工厂模式、原型模式、建造者模式1. 单例模式单例模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象单例模式的实现:饿汉式:类一加载就创建该实例对象懒汉式:需要使用时才创建该实例对象(1)饿汉式(静态变量方式)该方式在成员位置声明 Singleton 类型的静态变量,并创建 Singleton 类的对象 instance,instance 对象随着类的加载被创建,如果该类足够大且一直没有被使用的情况下会造成内存的浪费Singletonpublic class Singleton { //1.私有构造方法 private Singleton() { } //2.在本类中创建本类对象 private static Singleton instance = new Singleton(); //3.提供一个公共的访问方式,让外界获取该对象 public static Singleton getInstance() { return instance; } }Clientpublic class Client { public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); //true System.out.println(instance == instance1); } }(2)饿汉式(静态代码块方式)该方式在成员位置声明 Singleton 类型的静态变量,而对象的创建是在静态代码块中,也是随着类的加载而被创建,与静态变量方式类似Singletonpublic class Singleton { private Singleton() { } private static Singleton instance; static { instance = new Singleton(); } public static Singleton getInstance() { return instance; } }Clientpublic class Client { public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); //true System.out.println(instance == instance1); } }(3)懒汉式(线程不安全)当调用 getInstance() 方法获取 Singleton 类的对象的时候才创建 Singleton 类的对象,这样就实现了懒加载,但在多线程操作时存在线程不安全的问题Singletonpublic class Singleton { private Singleton() { } private static Singleton instance; public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }Clientpublic class Client { public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); //多线程操作时,存在线程不安全的问题 System.out.println(instance == instance1); } }(4)懒汉式(双重检测锁)使用 volatile 关键字保证可见性和防止指令重排(JVM在实例化对象时会进行优化和指令重排序操作,可能产生空指针)Singletonpublic class Singleton { private Singleton() { } //volatile保证可见性和防止指令重排 private static volatile Singleton instance; public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }Clientpublic class Client { public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); System.out.println(instance == instance1); } }(5)懒汉式(静态内部类)实例由内部类创建,由于JVM在加载外部类的过程中不会加载静态内部类,只有内部类的属性/方法被调用时才会被加载,并初始化其静态属性,其中静态属性由于被 static 修饰,保证只被实例化一次,并且严格保证实例化顺序说明:第一次加载 Singleton 类时不会去初始化 INSTANCE,只有第一次调用 getInstance() 时,虚拟机加载 SingletonHolder 并初始化 INSTANCE ,这样既保证了现成安全,也保证了 Singleton 的唯一性,在没有加任何锁的情况下保证了线程的安全且不造成性能和内存的浪费(双重检测锁方式 和 静态内部类方式可以任选其一)Singlepublic class Singleton { private Singleton() { } private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }Clientpublic class Client { public static void main(String[] args) { Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); System.out.println(instance == instance1); } }(6)枚举方式枚举是线程安全的,且只会被加载一次,注意枚举方式属于饿汉式Singletonpublic enum Singleton { INSTANCE; }Clientpublic class Client { public static void main(String[] args) { Singleton instance = Singleton.INSTANCE; Singleton instance1 = Singleton.INSTANCE; //true System.out.println(instance == instance1); } }(7)存在的问题破坏单例模式的方式:序列化和反序列化反射解决方法:序列化和反序列化 - 在单例类中添加 readResolve() 方法,在反序列化时,如果类中定义了这个方法,就返回这个方法的值,反之则创建新的对象反射 - 在单例类的构造方法中通过标志位来判断是否是第一次访问,且在该构造方法中需要加 synchronized 锁,锁该类 synchronized(Singleton.class)
2022年08月27日
46 阅读
0 评论
0 点赞