设计模型之单例设计

news/2024/6/30 10:38:23

前言

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:1.单例类只能有一个类。2单例类必须创建自己的唯一id.

  • 3、单例类必须给所有其他对象提供这一实例。

单例模式的实现

单例设计模式分为两种:

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

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

饿汉式实现方式一:静态变量方式

public class Singleton {

    //私有构造方法
    private Singleton(){

    }
    //2.在本类中创建本类对象
    private static  Singleton instance=new Singleton();

    //3.提供一个公共的访问方法,让外界获取该对象
    public static Singleton getInstance(){
        return instance;
    }
}
public class Main {
    public static void main(String[] args) {
        //创建Singleton类的对象
       Singleton instance= Singleton.getInstance();
       Singleton instance1= Singleton.getInstance();

        System.out.println(instance==instance1);
    }
}

 饿汉式实现方式二:静态代码块

public class Singleton {
    //1.私有构造方法,防止被外界创建
    private Singleton(){};

    //声明Singleton类型的变量
    private  static  Singleton instance;//null
    //在静态代码块中进行赋值
    static {
        instance=new Singleton();
    }
    //对外界提供获取该类对象的方法
    public static Singleton getInstance(){
        return instance;
    }


}
public class Main {

    public static void main(String[] args) {
        //创建Singleton类的对象
         Singleton instance= Singleton.getInstance();
         Singleton instance1= Singleton.getInstance();

        System.out.println(instance==instance1);
    }
}

 

  饿汉式实现方式三:枚举

public enum Singleton {
    INSTANCE;
}
public class Main {


    public static void main(String[] args) {
        //创建Singleton类的对象
       Singleton instance= Singleton.INSTANCE;
      Singleton instance1= Singleton.INSTANCE;

        System.out.println(instance==instance1);
    }

}

 

懒汉式实现方法一:(线程不安全)

public class Singleton {

    //1.私有构造方法,防止被外界创建
    private Singleton(){};

    //声明Singleton类型的变量,并没有进行赋值
    private  static Singleton instance;//null

    //对外界提供获取该类对象的方法
    public static Singleton getInstance(){
        if(instance==null)
        {
            instance=new Singleton();
        }

        return instance;
    }


}

但是这种方法在多线程里是不安全的,当有两个线程时,一个线程执行到判断语句判断instance是否为null时,处于等待状态,而另一个线程获得CPU的执行权,也会进行判断里面,这时会创建两个Singleton对象。

懒汉式实现方法二:加入synchronized 

public class Singleton {

    //1.私有构造方法,防止被外界创建
    private Singleton(){};

    //声明Singleton类型的变量,并没有进行赋值
    private  static Singleton instance;//null

    //对外界提供获取该类对象的方法
    public static synchronized Singleton getInstance(){
        if(instance==null)
        {
            instance=new Singleton();
        }

        return instance;
    }


}

 懒汉式实现方法三:双重检查方式

public class Singleton {

    //1.私有构造方法,防止被外界创建
    private Singleton(){};

    //声明Singleton类型的变量,并没有进行赋值
    private  static Singleton instance;//null

    //对外界提供获取该类对象的方法
    public static Singleton getInstance(){
        //第一次判断,如果instance的值不为null,不需要抢占锁,直接返回对象
        if(instance==null)
        {
            synchronized (Singleton.class){
                //第二次判断
                if(instance==null)
                {
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
}

双重检查锁模式的优缺点:缺点:可能会出现空指针问题。解决方法:使用volatile关键字。 volatile保证可见性和有序性。

 懒汉式实现方法四:静态内部类方式

public class Singleton {

    //1.私有构造方法,防止被外界创建
    private Singleton(){};

    //定义一个静态内部类
    private  static class SingletonHolder{
        //在内部类中声明并初始化内部类的对象
        private  static final Singleton INSTANCE=new Singleton();
    }

    //对外界提供获取该类对象的方法
    public static Singleton getInstance(){
        return SingletonHolder.INSTANCE;
    }
}

 静态内部类是一种优秀的单例模式,比较常用,在没有加锁的情况下,保证了多线程下的安全,并且没有任何性能影响和空间的浪费。


http://lihuaxi.xjx100.cn/news/307412.html

相关文章

【蓝桥杯】第十四届模拟赛第一期及第二期填空汇总

目录 1.A题(进制位数) 位运算符 第一期 问题描述 解析 第二期 解析 代码 2.B题(日期问题) 第一期 问题描述 解析 代码实现 执行结果 第二期 问题描述 解析 3.C题(数学问题) 第一期 问题…

4. 死信队列

二八佳人体似酥,腰间仗剑斩愚夫。虽然不见人头落,暗里教君骨髓枯。 死信 概念 先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理 解,一般来说,producer 将…

第十二章 Amortized Analysis平摊分析

第12章 Amortized Analysis平摊分析第10周 记于2022/11/29概率分析与平摊分析的区别概率分析平均执行时间考虑同一算法的所有可能输入情况 如果使用概率,则称为期望运行时间 针对单一操作/算法平摊分析针对某一数据结构的 操作序列 不使用概率 操作序列中的平均操作性能/代价【…

效率工具之Arthas

Arthas 阿里巴巴开源的Java诊断工具;追踪方法执行链、反编译、监控JVM状态 在线安装 使用 1. trace 跟踪调用链 解决痛点:定位问题根据日志推理分析,方法出入参不可见,分支判断太多情况下 定位很慢,分析出可能有问…

html5期末大作业——HTML+CSS公益关爱残疾人( 6个页面)

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

C++-关键字:auto

C98 auto 早在C98标准中就存在了auto关键字,那时的auto用于声明变量为自动变量,自动变量意为拥有自动的生命期,这是多余的,因为就算不使用auto声明,变量依旧拥有自动的生命期: int a 10 ; //拥有自动生命…

【算法】排序——直接排序

内部排序的全部过程都是在内存中进行的。按排序策略的不同可以将内部排序划分为直接插入排序、冒泡排序、简单选择排序、希尔排序、快速排序、堆排序、归并排序、基数排序等。其中前三种排序方法属于简单的排序方法,其特点是排序过程直观、易于理解和实现&#xff0…

Http协议和Https协议

Http是不安全的,你的数据容易被黑客拦截,篡改,攻击 https要求对数据加密(不能明文传输), 用抓包工具抓http请求,抓出来的都是明文的,你能看得懂的,抓https请求,抓出来的…