单例形式有几种写法 面试突击50 (单例类是什么)

单例形式有几种写法 面试突击50 (单例类是什么)

本文目录导航:

面试突击50:单例形式有几种写法?

单例形式是面试中的常客了,它的经常出现写法有 4 种:饿汉形式、懒汉形式、静态外部类和枚举,接上去咱们逐一来看。

1.饿汉形式

饿汉形式也叫预加载形式,它是在类加载时间接创立并初始化单例对象,所以它并不存在线程安保的疑问。它是依托 ClassLoader 类机制,在程序启动时只加载一次性,因此不存在线程安保疑问,它的实现代码如下:

public class Singleton {// 1.防止外部间接 new 对象破坏单例形式private Singleton() {}// 2.经过私有变量保留单例对象private static Singleton instance = new Singleton();// 3.提供公共失掉单例对象的方法public static Singleton getInstance() {return instance;}}

好处:成功便捷、不存在线程安保疑问。

缺陷:类加载时就创立了对象,创立之后假设没被经常使用,就形成了资源糜费的状况。

2.懒汉形式

懒汉形式和饿汉形式正好是同样的,所谓的懒汉形式也就是懒加载(提前加载),指的是它只要在第一次性被经常使用时,才会被初始化,它的实现代码如下:

public class Singleton {// 1.防止外部间接 new 对象破坏单例形式private Singleton() {}// 2.经过私有变量保留单例对象private static volatile Singleton instance = null;// 3.提供公共失掉单例对象的方法public static Singleton getInstance() {if (instance == null) { // 第一次性效验synchronized () {if (instance == null) { // 第二次效验instance = new Singleton();}}}return instance;}}

懒汉形式经常使用的是双重效验锁和 volatile 来保障线程安保的,从上述代码可以看出,无论是饿汉形式还是懒汉形式,它们的成功步骤都是一样的:

创立一个私有的结构方法,防止其余调用的中央间接 new 对象,这样创立进去的对象就不是单例对象了。

创立一个私有变量来保留单例对象。

提供一个公共的方法前往单例对象。

懒汉形式相比于饿汉形式来说,不会形成资源的糜费,但写法要复杂一些。

3.静态外部类

静态外部类既能保障线程安保,又能保障懒加载,它只要在被调用时,才会经过 ClassLoader 机制来加载和初始化外部静态类,因此它是线程安保的,此形式的实现代码如下:

public class Singleton {// 1.防止外部间接 new 对象破坏单例形式private Singleton() {}// 2.静态外部类private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}// 3.提供公共失掉单例对象的方法public static final Singleton getInstance() {return ;}}4.枚举

枚举也是在第一次性被经常使用时,才会被 Java 虚构机加载并初始化,所以它也是线程安保的,且是懒加载的,它的实现代码如下:

public enumEnumSingleton {INSTANCE;public EnumSingleton getInstance(){return INSTANCE;}}总结

单例形式实用于经常被访问的对象,或是创立和销毁须要调用少量资源和期间的对象,经常使用单例形式可以防止频繁创立和销毁对象。

单例形式的罕用成功方法有 4 种:饿汉形式、懒汉形式、静态外部类和枚举。

从写法的繁复性、线程安保性和代码的易懂性等方面综合来看,博主比拟介绍经常使用枚举或懒汉形式来成功单例形式。

是非审之于己,毁誉听之于人,得失安之于数。

群众号:Java面试真题解析

面试合集:原文:

设计形式之单例形式

单例设计形式了解起来十分便捷。

一个类只准许创立一个对象(或许实例),那这个类就是一个单例类,这种设计形式就叫单例形式。

上方的示例中假设每个类都创立一个 Logger 实例,就或许形成日志内容被笼罩的状况。

假设有些数据在系统中只应保留一份,那就比拟适宜设计为单例类。

比如,性能消息类,全局 ID 生成器等。

要成功一个单例,咱们要思考以下几点:

懒汉式相关于饿汉式的好处是「支持提前加载」 。

但缺陷也很显著,由于经常使用了 synchronized 主要字造成这个方法的「并发度很低」 。

假设这个单例类偶然会被用到,那这种成功形式还可以接受。

然而,假设频繁地用到,就会造成性能瓶颈,这种成功形式就无法取了。

这是一种既支持提前加载、又支持高并发的单例成功形式。

在 java1.5 以下 instance = new Singleton(); 有指令重排疑问,须要给 instance 成员变量加上 volatile 主要字,java1.5 之后不会再这个疑问。

这种形式应用了 Java 的静态外部类,有点相似饿汉式,但又能做到了提前加载。

当外部类 Singleton 被加载的时刻,并不会创立 SingletonHolder 实例对象。

只要当调用 getInstance() 方法时,SingletonHolder 才会被加载,这个时刻才会创立 instance。

insance 的惟一性、创立环节的线程安保性,都由 JVM 来保障。

所以,这种成功方法既保障了线程安保,又能做到提前加载。

这是一种最便捷的成功形式,基于枚举类型的单例成功。

这种成功形式是经过 Java 枚举类型自身的个性,保障了实例创立的线程安保性和实例的惟一性。

上方的单例类对象是进程惟一的,一个进程只能有一个单例对象。那如何成功一个线程惟一的单例呢?

假定 IdGenerator 是一个线程惟一的单例类。

在线程 A 内,咱们可以创立一个单例对象 a。

由于线程内惟一,在线程 A 内就不能再创立新的 IdGenerator 对象了,而线程间可以不惟一,所以,在另外一个线程 B 内,咱们还可以从新创立一个新的单例对象 b。

咱们经过一个 ConcurrentHashMap 来存储对象,其中 key 是线程 ID,value 是对象。

这样咱们就可以做到,不同的线程对应不同的对象,同一个线程只能对应一个对象。

实践上,Java 言语自身提供了 ThreadLocal 工具类,可以愈加轻松地成功线程惟一单例。

如何解读java中的设计形式下的getinstance()方法?

单例形式在Java中是一种设计形式,确保一个类只创立一个实例,并提供一个全局访问点,使得其余对象可以访问该实例。

这种形式有助于节俭资源并简化治理,防止创立过多对象,特意是在须要控制全局形态的运行中。

成功单例形式的主要在于确保实例化环节的惟一性与分歧性。

接上去,咱们将讨论经常使用枚举成功单例形式的好处与示例代码。

经常使用枚举成功单例形式是一个繁复且安保的形式。

每个枚举常量都是该枚举类型的惟一实例,因此,只要定义枚举常量作为单例对象,即可确顾全局惟一性。

以下是枚举成功单例形式的代码示例:

javapublic enum Singleton {INSTANCE;}

由于枚举常量的惟一性,`INSTANCE`成为了`Singleton`的惟一实例。经常使用枚举成功单例形式具备以下好处:

接上去,咱们将回答一些关于单例形式的疑问,以深化了解其用法与特点。

疑问与答案

1)什么是单例形式?

单例形式是一种设计形式,确保一个类只要一个实例,并提供全局访问点以供其余对象访问。

这种形式用于控制全局资源的访问,如日志系统、数据库衔接池等。

2)如何成功单例形式?

成功单例形式的形式有多种,包含饿汉式、懒汉式、双重审核锁定和静态外部类等。

其中,饿汉式和静态外部类在多线程环境下具备线程安保性,而懒汉式和双重审核锁定则须要额外的同步措施来确保线程安保。

3)为什么经常使用单例形式?

经常使用单例形式可以缩小资源消耗,防止创立不用要的对象实例,特意是在须要治理全局形态的运行中。

它有助于简化代码、提高性能,并确顾全局资源的分歧性。

4)单例形式有哪些优缺陷?

好处:简化资源治理、缩小内存消耗、提高系统性能、确顾全局资源分歧性。

缺陷:违犯开闭准则,单例类的修正或许影响一切经常使用该类的模块,造成代码耦合度参与;或许影响系统可测试性。

5)如何保障单例形式的线程安保?

可以经过同步主要字(如`synchronized`)、volatile主要字、静态外部类等形式成功线程安保的单例形式。

其中,饿汉式和静态外部类是最经常出现的线程安保成功形式。

单例形式在Spring框架中的运行

在Spring框架中,单例形式用于治理Bean的实例化与生命周期。

Spring自动将大局部Bean设置为单例形式,确顾全局惟一性。

Spring经过作用域、提前初始化和生命周期回调等性能,提供了一种灵敏且牢靠的Bean治理形式。

1)Bean的作用域

自动状况下,Spring中的Bean是单例的,象征着它们只实例化一次性,可供多个对象共享。

Spring还支持其余作用域,如原型、恳求、会话和全局会话。

2)生命周期回调

Spring提供多个回调方法,用于治理Bean的生命周期,包含初始化前、初始化后、销毁前和销毁后等。

经过成功这些回调方法,可以对Bean的生命周期启动精细控制,提高运行的牢靠性和稳固性。

在单例形式下,Bean的初始化和销毁仅出现一次性。

综上所述,单例形式在Java和Spring框架中具备宽泛的运行,提供了高效、繁复且安保的实例化与治理形式。

了解单例形式的成功与个性,将有助于构建愈加灵敏和可保养的系统。

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

26阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

26阅读