单例模式双重校验锁

164 阅读2分钟

笔记迁移

创建型

单例模式

单例模式: 确保每个类只有一个实例

结构:私有构造函数,私有静态变量,公有静态函数

私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。

懒汉式

需要用到时才创建对象

线程不安全,多个线程进入 if(uniqueInstance == null),并且uniqueInstacne为null时,会多次创建对象。

image.png

image.png

image.png

饿汉式

系统加载时就创建对象(静态全局变量),线程安全,缺点是不用到时也加载创建浪费内存

image.png

【双重校验锁】线程安全的懒汉式

对getUniqueInstance()方法加synchronized锁,这没啥好说的,但性能不行

双重校验

这些线程想要进入方法时都要排队等待,有时候当第一个执行的线程已经创建好对象时,其他线程完全可以根据判断不为空直接返回对象,而不是继续排队等待,所以锁创建对象的代码块就行了

第一次校验是针对不为空的情况这样很快,那么为空的情况其他线程仍然可以按顺序进入锁的代码块创建对象,所以要加第二次判断,防止创建多个实例,加volatile关键字防止JVM优化指令重排

image.png

静态内部类

属于懒汉式,只有在调用方法时才会触发内部静态类的加载,然后创建一个全局的静态变量

image.png

【最佳实践】枚举类

单例模式最佳实践

image.png

场景

查看Spring框架的源码用到单例模式的地方,很熟悉了吧QWQ他也锁的代码块然后再判空,而不是直接锁方法

image.png

工厂模式

实例化操作单独放到一个类里,然后根据条件决定让工厂创建哪些实例

简单工厂模式

顾名思义,最简单的实现工厂模式

image.png

image.png 多写几这样要被实例化的类

image.png

简单工厂

image.png 测试

image.png

image.png

工厂方法

把创建对象的操作放到工厂抽象类的各种子类的方法中,满足开闭原则,对修改关闭,对扩展开放

添加新产品时不必修改工厂,直接添加个类就行

image.png

image.png

image.png

抽象工厂方法

抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同

抽象工厂定义我们需要一起创建哪些对象

image.png 其他工厂继承抽象工厂

image.png