侧边栏壁纸
博主头像
七字节 博主等级

行动起来,活在当下

  • 累计撰写 10 篇文章
  • 累计创建 40 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

设计模式-单例设计模式

七字节
2025-02-20 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

设计模式-单例设计模式

设计模式-单例设计模式

单例设计模式属于设计模式中的创建者模式。

定义:单例设计模式指单例类只能创建一个对象。

这个类提供了一种访问其唯一对象的方式,可以直接访问,不需要实例化该类的对象。

单例设计模式实现分为两种:

饿汉式:类加载就会导致该单实例对象被创建。

懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会创建。

懒汉式只有在需要的时候才加载,可以节省内存空间。

单例设计模式有多种实现,其中双重检查锁应该是最重要的实现方式之一,属于懒汉式。

饿汉式:

在类加载时就创建了该类的实例对象,可以通过getInstance()方法获取该类的单实例对象。

//饿汉式

public class Singleton {

    private static final Singleton singleton = new Singleton();

    private String name;

    private Singleton(){

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public static Singleton getInstance(){

        return singleton;

    }

}

懒汉式 - 双重检查锁模式

双重检查锁模式是为了避免在多线程中单例模式失效的情况下产生的,第一次判断是为了避免非必要加锁,synchronized (Singleton.class)加锁是为了避免多线程情况下多个线程同时来到第二个判断产生多个Singleton类实例。

//懒汉式 - 双重检查锁模式

//若是每个线程都必须等待其他线程释放锁才能获取单实例,则会造成性能的低下

//而读取操作是不会有线程安全的问题的,所以对于读操作不必等待,获取锁

public class Singleton {

    private static volatile Singleton singleton = null;

    private String name;

    private Singleton(){}

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public static Singleton getInstance(){

//        双重检查锁

        if(singleton == null){

            synchronized (Singleton.class){

                if(singleton == null){

                    singleton = new Singleton();

                }

            }

        }

        return singleton;

    }

}

懒汉式 - 静态内部类模式:

//懒汉式 - 静态内部类模式

public class Singleton {

    private Singleton(){}

    private String name;

    private static class SingleTonHolder{

        private static final Singleton INSTANCE = new Singleton();

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public static Singleton getInstance(){

        return SingleTonHolder.INSTANCE;

    }

}

当加载外部类时并不会立即加载内部类而内部类没有被加载则不会初始化 INSTANCE ,即

当初始化外部的Singleton时,并不会立即加载内部的SingleTonHolder,只有当getInstance()方法第一次被调用时才会加载 INSTANCE。

饿汉式 - 枚举:

//饿汉式 - 使用枚举创建单实例

public enum Singleton {

    INSTANCE;

    private String name;

    public void setName(String name){

        this.name = name;

    }

    public String getName(){

        return this.name;

    }

}

使用枚举创建单例对象不会被反射给破坏, 因为每一个枚举类型和枚举变量在JVM中都是唯一的。

懒汉式-双重检查锁+readResolve() :

如果想使用双重检查锁的方式来创建单实例又想避免被反射破坏单例,可以加上readResolve() 方法:

import java.io.Serial;

import java.io.Serializable;

//懒汉式 - 使用readResolve()方法避免反射破坏单例模式

public class Singleton implements Serializable {

    @Serial

    private static final long serialVersionUID = 1L;

    private static volatile Singleton singleton = null;

    private Singleton(){}

    private String name;

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public static Singleton getInstance(){

        if(singleton == null){

            synchronized (Singleton.class){

                if(singleton == null){

                    singleton = new Singleton();

                }

            }

        }

        return singleton;

    }

    //当进行反序列化时,会自动调用该方法,将该方法的返回值直接返回,避免序列化可能导致的单例模式被破坏

    public Object readResolve(){

        return Singleton.getInstance();

    }

}
0

评论区