单例模式

只有一个实例且自己创建自己的唯一实例且给其他对象提供这一实例。

优点

  • 在内存中只有一个对象,节省内存空间
  • 避免频繁的创建销毁对象,可以提高性能
  • 避免对共享资源的多重占用
  • 可以全局访问

    懒汉式

    用到时才创建实例,加上synchronized线程安全
  1. public class Singleton(){
  2. private static Singleton singleton = null;
  3. private Singleton(){}
  4. public static Singleton getInstance(){
  5. if(singleton==null){
  6. singleton = new Singleton();
  7. }
  8. return singleton;
  9. }
  10. }

如果此时有两个线程,线程A执行到1处,读取了instance为null,然后cpu就被线程B抢去了,此时,线程A还没有对instance进行实例化。因此,线程B读取instance时仍然为null,于是,它对instance进行实例化了。然后,cpu就被线程A抢去了。此时,线程A由于已经读取了instance的值并且认为它为null,所以,再次对instance进行实例化。所以,线程A和线程B返回的不是同一个实例。
引发了单例模式的线程不安全问题。

线程安全的:

  1. public class Singleton(){
  2. private volatile static Singleton singleton = null;
  3. private Singleton(){}
  4. public static Singleton getInstance(){
  5. if(singleton==null){
  6. synchronized(Singleton.class){
  7. if(singleton==null){
  8. singleton = new Singleton();
  9. }
  10. }
  11. }
  12. return singleton;
  13. }
  14. }

采用双重锁机制+volatile关键字禁止指令重排序
程序运行顺序:

  1. 给instance实例分配内存
  2. 初始化instance的构造器
  3. 将instance对象指向分配的内存空间

由于jvm的指令重排序机制,运行顺序有可能为1.3.2,这时走到3的时候instance已经不为null了

饿汉式

类加载时就创建对象

  1. public class Singleton(){
  2. private static singleton = new Singleton();
  3. private Singleton singleton(){}
  4. public static Singleton getInstance(){
  5. return singleton;
  6. }
  7. }

枚举方式

  1. public enum Singleton{
  2. instance
  3. public Singleton getInstance(){
  4. return instance;
  5. }
  6. }

工厂模式

多个类实现同一接口。工厂类根据不同的输入参数返回不同类型的对象
image.png
输入参数
FactoryPatternDemo—————>ShapeFactory———————>返回不同类型的对象

抽象工厂模式

围绕一个超级工厂创建其他工厂
image.png

FactoryProducer::getFactory()获取到对应的工厂—->进而获取对象

适配器模式

作为两个不兼容接口的桥梁
image.png

装饰器模式

允许向一个现有对象添加新功能,同时不改变其结构。
image.png

代理模式

一个类代表另一个类的功能
由代理对象控制对原对象的访问,可以增添需要的新功能。