首页 > 编程语言 >Java设计模式--单例模式(懒汉式实现)

Java设计模式--单例模式(懒汉式实现)

时间:2024-11-13 10:19:19浏览次数:3  
标签:加锁 Java -- SingletonLazy instance 实例 线程 设计模式 -------------------------

1、单例模式(Singleton Pattern)

        单例模式是一种常见的设计模式,目的是确保一个类只会存在一个实例,并且该类提供全局进行访问此实例的方法。

2、懒汉式

/**
 * @author Hao
 * 单例模式:懒汉式
 * 懒汉式是线程不安全的,懒汉式在多线程环境下,可能会出现多个实例,所以需要加锁。
 * 懒汉式可以延迟加载,不会在首次加载时就初始化,而是在调用时才创建。
 *
 * 总结:
 *     优点:延迟加载,减少内存开销。
 *     缺点:在多线程环境下,可能会出现多个实例。
 */

 2.1、方法一:双重检查锁

// 方法一:双重检查锁

// -------------------------方法一开始-------------------------

// 私有化定义实例
private static volatile SingletonLazy instance;

/**
 * 提供公共获取实例方法
 * @return SingletonLazy 实例
 * 使用双重判断加锁,而不直接于方法上加锁,是为了避免每次调用getInstance()方法时,
   都进行加锁,造成不必要的开销。
 */
public static SingletonLazy getInstance(){
    // 第一次判断,判断是否已经实例化,如果已经实例化,那么就不会被多线程影响
        出现创建多个实例的情况,所以直接返回
    if (instance == null){
        // 如果没有实例化,那么就加锁,避免多线程下,多个线程同时创建实例的情况
        synchronized (SingletonLazy.class){
            // 此时进行第二次判断,避免多个线程同时访问抢锁,导致创建多个实例。举个例子
            // 线程a、b同时访问,此时instance还未实例化。那么此时线程a、b都会通
                过第一次判断。
            // 这时线程a率先强到锁,如果不进行二次判断,线程a创建实例后,线程b获得锁
                也会创建实例,从而造成多个实例。
            if (instance == null){
                instance = new SingletonLazy();
            }
        }
    }
    return instance;
}

// -------------------------方法一结束-------------------------

2.2、方法二: 静态内部类

// 方法二:静态内部类

// -------------------------方法二开始-------------------------

// 创建私有内部类,提供实例
private static class SingletonHolder{
    private static final SingletonLazy instance = new SingletonLazy();

}

/**
 * 提供公共获取实例方法
 * @return SingletonLazy 实例
 *
 * 使用静态内部类,避免了线程不安全,延迟加载,效率更高。
 * 静态内部类在第一次使用的时候才会被加载,不会造成内存浪费。
 */
public static SingletonLazy getSingleton(){
    return SingletonHolder.instance;
}

// -------------------------方法二结束-------------------------

2.3、方法三:枚举类

/**
 * @author Hao
 *
 * 通过枚举方式创建
 */
public enum Singleton {

    // 没错就是这么简单 =.=,而且枚举的实例化是线程安全的、不会被破坏的。
    INSTANCE;

    private String name;

    public String getName() {
        return name;
    }

}

 3、完整代码


/**
 * @author Hao
 * 单例模式:懒汉式
 * 懒汉式是线程不安全的,懒汉式在多线程环境下,可能会出现多个实例,所以需要加锁。
 * 懒汉式可以延迟加载,不会在首次加载时就初始化,而是在调用时才创建。
 *
 * 总结:
 *     优点:延迟加载,减少内存开销。
 *     缺点:在多线程环境下,可能会出现多个实例。
 */
public class SingletonLazy {

    // 私有化构造函数
    private SingletonLazy(){}

    // 方法一:双重检查锁

    // -------------------------方法一开始-------------------------

    // 私有化定义实例
    private static volatile SingletonLazy instance;

    /**
     * 提供公共获取实例方法
     * @return SingletonLazy 实例
     * 使用双重判断加锁,而不直接于方法上加锁,是为了避免每次调用getInstance()方法时,都进行加锁,造成不必要的开销。
     */
    public static SingletonLazy getInstance(){
        // 第一次判断,判断是否已经实例化,如果已经实例化,那么就不会被多线程影响出现创建多个实例的情况,所以直接返回
        if (instance == null){
            // 如果没有实例化,那么就加锁,避免多线程下,多个线程同时创建实例的情况
            synchronized (SingletonLazy.class){
                // 此时进行第二次判断,避免多个线程同时访问抢锁,导致创建多个实例。举个例子
                // 线程a、b同时访问,此时instance还未实例化。那么此时线程a、b都会通过第一次判断。
                // 这时线程a率先强到锁,如果不进行二次判断,线程a创建实例后,线程b获得锁也会创建实例,从而造成多个实例。
                if (instance == null){
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }

    // -------------------------方法一结束-------------------------



    // -----------------------------------------------------------------------------------------------------------------



    // 方法二:静态内部类

    // -------------------------方法二开始-------------------------

    // 创建私有内部类,提供实例
    private static class SingletonHolder{
        private static final SingletonLazy instance = new SingletonLazy();

    }

    /**
     * 提供公共获取实例方法
     * @return SingletonLazy 实例
     *
     * 使用静态内部类,避免了线程不安全,延迟加载,效率更高。
     * 静态内部类在第一次使用的时候才会被加载,不会造成内存浪费。
     */
    public static SingletonLazy getSingleton(){
        return SingletonHolder.instance;
    }

    // -------------------------方法二结束-------------------------

}

4、饿汉式

Java设计模式--单例模式(饿汉式实现)-CSDN博客

标签:加锁,Java,--,SingletonLazy,instance,实例,线程,设计模式,-------------------------
From: https://blog.csdn.net/qq_65225921/article/details/143731841

相关文章

  • 如何选择CMS网站管理系统来创建网站呢?
    在网站规划中,选择一个合适的CMS(内容管理系统)尤其重要。CMS是一种用于制作、编辑和管理网站内容的建站工具,它能降低建站的难度、节省建站的时间、提高网站创建的效率和质量。当然、想提高网站创建的质量,还是得选对CMS,但是市场上有各种不同类型的CMS品牌,那么如何选择适合自己......
  • 什么是“优先劣后”
    在财务中,“优先劣后”是一种风险和收益的安排方式,它涉及到资金的偿还顺序和收益分配。具体来说,“优先”指的是在投资或融资活动中,某些资金或投资者在收益分配或损失承担时享有优先权,即他们先于其他资金或投资者获得收益或偿还本金。而“劣后”则是指在同样的活动中,某些资金或投资......
  • Sql优化技巧总结(面试必刷!!!)
    摘要    近段时间,面试官关于Sql优化的提问已经越来越多了,Sql优化可以说是已经成为了面试必备技能之一。本文从Sql语句、硬件设备以及Java程序三个方面详细的讲解关于Sql优化的技巧。目录摘要一、Sql语句优化1、避免使用Select*总结2、使用(创建)索引2.1、不能......
  • 解决高版本laravel/framework中SQLServer2008分页报错问题
    前提:laravel自6.0后就明确了支持的SQLServer版本最低为2017,而SQLServer是在2012版本后,引入的offset语法来实现分页,在此之前只能使用ROW_NUMBER()函数来完成分页。问题:生产环境的SQLServer由于历史原因,仍旧使用的2008版本,自然是不支持offset语法的,而新建项目使用的laravel版本......
  • laravel PhpOffice 读取表格数据
    /***更新安通船期*Description*AuthorAllen*Date2024-11-11*@paramRequest$request[description]*@return[type][description]*/publicfunctionupdateAntongShipDate(Request$request){......
  • Linux内存管理,它的价值?面试被问过吗?
    Linux内核的内存管理是操作系统最基础且关键的部分之一。它直接影响系统性能、资源分配的效率和多任务管理的稳定性。掌握Linux内核的内存管理,不仅能够帮助我们理解操作系统如何调度资源,还能优化应用程序的性能。在面试中,内存管理常常是考察系统设计、操作系统基础和调优......
  • RadSystems 自定义页面全攻略:个性化任务管理系统的实战设计
    系列文章目录探索RadSystems:低代码开发的新选择(一)......
  • Python绘制循环渐变圆
    通过改变颜色,圆的半径,及旋转角度来形成圆图形importturtleimportcolorsysascs#导入颜色转换模块#设置显示屏幕screen=turtle.Screen()screen.title("渐变色的圆")screen.bgcolor('#AFEEEE')#设置画笔p=turtle.Turtle()p.pensize(1)p.speed(0)#设置......
  • 昱合昇|11cj33通风采光天窗图集的系列窗型
    在建筑设计中,通风和采光一直是重要的考虑因素。为了满足建筑物内的通风和采光需求,设计师们通常会选择安装通风采光天窗。11CJ33《通风采光天窗》图集提供了多种系列的窗型,以满足不同建筑的需求。11CJ33《通风采光天窗》图集包括了多种类型的天窗,如薄型通风天窗、流线型通......
  • 昱合昇|一字型排烟天窗如何快速实现采光排烟?
    一字型排烟天窗是一种特殊设计的通风天窗,能够实现高效采光和排烟功能。电动采光排烟天窗采用了一字型的开启方式,可以同时打开两个相对的窗扇,形成自然的通风通道。1、高效排烟:通过打开天窗,一字型排烟天窗可以快速排出室内的烟雾、有害气体和热空气,改善室内环境。2、大面积通......