首页 > 编程语言 >Java设计模式之单例模式

Java设计模式之单例模式

时间:2023-06-01 21:55:09浏览次数:61  
标签:Java getInstance 模式 instance 实例 static 单例 设计模式

一、何谓单例模式?

单例模式,也叫单子模式,是一种常用的软件设计模式,属于创建型模式的一种。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。

单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。

单例模式中比较常见的就是饿汉式懒汉式多线程下的双重检查锁式,以下分别进行Java代码实现:

二、单例模式代码实现

饿汉式

/* 单例模式:饿汉式 */
public class EagerSingletonTest {
    private EagerSingletonTest() {} // 1. 私有化构造器,防止外部直接创建(暂且不考虑反射的影响)

    private final static EagerSingletonTest instance = new EagerSingletonTest(); // 2. 饿汉式,所以就得提前把对象创建好,并声明为final和static,因为“他”太饿了

    public static EagerSingletonTest getInstance(){ // 3. 定义获取单例实例的方法getInstance(),外界可以直接EagerSingletonTest.getInstance()来获取单例对象
        return instance;
    }
}

懒汉式

/* 单例模式:懒汉式 */
public class LazySingletonTest {
    private LazySingletonTest() {} // 1. 私有化构造器,防止外部直接创建(暂不考虑反射的影响)

    private static LazySingletonTest instance = null; // 2. 懒汉式,总是到deadline的时候才创建对象,因为“他”太懒了,所以初始化为null

    public static LazySingletonTest getInstance(){ //3. 定义获取单实例的方法getInstance(),外界可以直接调用,并获取单例对象
        if(instance == null){
            instance = new LazySingletonTest(); //4. 到了deadline了,才new一个对象供全局使用
        }
        return instance;
    }
}

双重检查锁式

/* 单例模式:双重检查锁(多线程懒汉增强式) */
public class DoubleCheckLockSingletonTest {
    private DoubleCheckLockSingletonTest() {}; // 第一步:私有化构造器,防止外部直接创建

    private static volatile DoubleCheckLockSingletonTest instance = null; // 第二步:利用懒汉式,并添加volatile防止指令重排

    public static DoubleCheckLockSingletonTest getInstance(){
        if(instance == null){ // 减少多线程时并发时后续线程的阻塞状况,提高性能
            synchronized(DoubleCheckLockSingletonTest.class){
                if(instance == null){ // 保证单例
                    instance = new DoubleCheckLockSingletonTest();
                }
            }
        }
        return instance;
    }
}

标签:Java,getInstance,模式,instance,实例,static,单例,设计模式
From: https://www.cnblogs.com/fxy0715/p/17450261.html

相关文章

  • JavaScript 基础知识总结
    概述JavaScript基础分为三个部分:ECMAScript:JavaScript的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。DOM:DocumentObjectModel(文档对象模型),操作页面上的元素的API。比如让盒子移动、变色、改变大小、轮播图等等。BOM:BrowserObjectModel(浏览器对象模型),操......
  • javascript设计模式-责任链
    责任链可以用来消除请求的发送者和接收者之间的耦合,这是通过实现一个由隐式地对请求进行处理的对象组成的链而做到的。链中的每个对象可以处理请求,也可以将其传给下一个对象。JS内部就使用了这种模式来处一事件捕获和冒泡问题。一般的结构如下:发送者知道链中的第一个接收者,它向这个......
  • Java多线程 有ABC 3 个线程,线程C需要等待线程AB执行完成才能执行的实现方式
    https://blog.csdn.net/qq_42337969/article/details/118073089?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-1-118073089-blog-52536071.235^v36^pc_relevant_default_base3&depth_1-utm_sour......
  • Java判断当前系统类型
    Stringos=System.getProperty("os.name");if(os.toLowerCase().startsWith("win")){System.out.println(os+"can'tgunzip");}System类publicstatic Properties getProperties(String) 方法参数还可以有以下取值:java.versionJava运行......
  • Java 对象转 Json
    <!--json依赖--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.11.2</version></dependency>......
  • volatile与java内存模型
    一、结论先说结论,volatile能保证可见性和有序性,不能保证原子性。二、volatile的内存语义当写一个volatile变量时,会将变量值刷新回主内存当读一个volatile变更时,会从主内存中读取最新值三、内存屏障是什么?内存屏障是一类同步屏障指令,是cpu或编译器在对内存随机访问操作的一......
  • JAVA面试题整理
    本文分为十九个模块,分别是:「Java基础、容器、多线程、反射、对象拷贝、JavaWeb、异常、网络、设计模式、Spring/SpringMVC、SpringBoot/SpringCloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM」,如下图所示:   共包含208道面试题,本文的......
  • 常用的Java Enum JdbcType
    常用的JavaEnumJdbcTypeARRAYBIGINTBINARYBITBLOBBOOLEANCHARCLOBCURSORDATEDECIMALDOUBLEFLOATINTEGERLONGVARBINARYLONGVARCHARNCHARNCLOBNULLNUMERICNVARCHAROTHERREALSMALLINTSTRUCTTIMETIMESTAMPTINYINTUNDEFINEDVARBINARYVARCHAR参考资料......
  • Java 基本知识——first day
    注释注释不会被执行,是写给看代码的人看的。三种注释单行注释多行注释文档注释标识符关键字Java常见的关键字考点总结四个点:首字母应该以字母、$、_开始;开始后可以任意字符;不可用关键字大小写敏感 数据类型Java是一门强类型语言强类型语言比如......
  • Java多线程三(线程池执行完后再执行主线程)CountDownLatch
      我们在开发多线程的时候,有两种情况一种是我们处理好后,不用管结果。比如我需要查询某些数据然后存在数据库里。还有一种就是查询好数据(通过线程池),然后导出数据。这个就比较麻烦。因为我们要将数据通过多线程处理后,返回一个统一的结果。(由于多线程是在不同的时候执行数据),假如执......