教你java面试时如何聊单例模式

当被问到单例模式的时候,需要掌握以下几点:

1.单例模式定义及应用场景

单例模式是一种创建型设计模式,用于确保某个类只有一个实例,且该实例提供了全局访问点。该模式常用于线程池、日志、缓存、配置文件等需要只有一个实例的对象。

2.单例模式的实现方法

  • 饿汉式

在类加载的时候就将单例对象创建好,因此不存在线程安全问题,但是会浪费一定的内存空间。

public class Singleton {
    private static final Singleton instance = new Singleton();
    private Singleton(){}
    public static Singleton getInstance(){
        return instance;
    }
}
  • 懒汉式

在需要使用单例对象时才创建,在多线程情况下可能会存在线程不安全问题,例如线程 A 和线程 B 同时尝试获取单例对象,A 获取到锁初始化单例之后,B 可能会再次进入 if 语句中,从而创建出新的实例。

public class Singleton {
    private static Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        if (instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}
  • 双重校验锁

通过双重判断,保证线程安全,同时提高了效率。

public class Singleton {
    private static volatile Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

3.单例模式的线程安全性问题

  • 线程不安全

在多线程场景下,单例模式的实现可能会存在线程安全问题。

public class Singleton {
    private static Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        if (instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}
  • 线程安全

使用volatile和synchronized等关键字可以保证单例模式的线程安全。

public class Singleton {
    private static volatile Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

示例说明

示例1:懒汉式线程不安全示例

public class SingletonDemo {
    public static void main(String[] args) {
        Runnable runnable = () -> {
            Singleton singleton = Singleton.getInstance();
            System.out.println(singleton.hashCode());
        };
        Thread thread1 = new Thread(runnable, "Thread-1");
        Thread thread2 = new Thread(runnable, "Thread-2");
        thread1.start();
        thread2.start();
    }
}

示例输出:

217227986
1842773630

示例2:双重校验锁线程安全示例

public class SingletonDemo {
    public static void main(String[] args) {
        Runnable runnable = () -> {
            Singleton singleton = Singleton.getInstance();
            System.out.println(singleton.hashCode());
        };
        Thread thread1 = new Thread(runnable, "Thread-1");
        Thread thread2 = new Thread(runnable, "Thread-2");
        thread1.start();
        thread2.start();
    }
}

示例输出:

168044823
168044823

以上两个示例展示了懒汉式和双重校验锁两种单例模式的实现方式及其线程安全性问题。同时还介绍了单例模式的定义及应用场景。在面试中,可以根据面试官的问题来展开讨论,并举一些实际项目中的应用场景来巩固知识。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:教你java面试时如何聊单例模式 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • SpringData Repository接口用法解析

    SpringData Repository接口用法解析 Spring Data是Spring提供的一组库和工具,用于简化数据库访问和操作。其中,Spring Data Repository是一个简化数据访问层实现的框架,提供了一种基于接口的形式,可以自动生成实现类的方法,大大减少了实现数据访问层和数据库操作的代码工作量。本文将介绍SpringData Rep…

    Java 2023年5月20日
    00
  • 利用Java将2019拆分成三个素数平方和的方法实例

    下面是详细的攻略: 1. 前置知识 在理解“将2019拆分成三个素数平方和”的方法之前,需要掌握以下基本知识: 素数:一个大于1的数,如果仅能被1和它本身整除,则称之为素数。例如:2、3、5、7、11、13等。 平方和:多个数平方后的和。 2. 解法概述 根据题目要求,需要将数字2019拆分成三个素数的平方和。由于2019是一个奇数,所以其中至少一个素数必须…

    Java 2023年5月23日
    00
  • c# 实现雪花分形的示例

    C# 实现雪花分形的示例攻略 什么是雪花分形 雪花分形指的是由Koch曲线组成的图形。Koch曲线是一条无限长的分形曲线,由等边三角形递归地扩展而来。 实现步骤 第一步:绘制基础图形 首先,我们需要绘制一个等边三角形,作为雪花分形的基础图形。 Graphics g = this.CreateGraphics(); Pen pen = new Pen(Colo…

    Java 2023年5月26日
    00
  • jsp 自定义标签实例

    这里是关于JSP自定义标签实例的完整攻略,包含两个示例说明。 什么是JSP自定义标签 JSP自定义标签(JSP Custom Tag)是JSP中的一种高级技术,可以让开发者将复杂的业务逻辑隐藏在标签中,使JSP页面更容易维护和修改。 JSP自定义标签分为两种: 标签文件(tag file):即后缀名为.tag的文件,通常用于较复杂的逻辑处理。标签文件可以通过…

    Java 2023年6月15日
    00
  • SSH框架网上商城项目第23战之在线支付功能实现

    SSH框架网上商城项目第23战之在线支付功能实现 1. 确认在线支付接口 首先,在实现在线支付功能之前,我们需要确认使用哪种在线支付接口,比如使用支付宝、微信等。针对每种接口,都有对应的API文档可以供开发人员参考。这里以使用支付宝支付为例进行说明。 2. 导入支付宝SDK 在使用支付宝API之前,我们需要先在项目中导入支付宝SDK。具体操作步骤如下: 访问…

    Java 2023年6月16日
    00
  • Spring Boot 集成JWT实现前后端认证的示例代码

    下面是详细讲解“Spring Boot集成JWT实现前后端认证的示例代码”的攻略。 什么是JWT JWT全称为JSON Web Token。它是一种轻量级的身份验证机制,可以用于前后端之间的认证和授权。使用JWT进行认证,可以避免服务端为每个客户端的请求保存会话状态,从而提高服务的可伸缩性。 JWT由三部分组成:头部(Header)、载荷(Payload)和…

    Java 2023年5月20日
    00
  • Java 开发环境配置步骤(介绍)

    下面是 Java 开发环境配置步骤的详细攻略。 Java 开发环境配置步骤(介绍) 确认电脑是否已安装 Java 开发环境 在开始配置 Java 开发环境之前,我们需要先确认电脑是否已经安装了 Java 开发环境。打开终端(或命令提示符)输入以下命令: java -version javac -version 如果电脑已经安装了 Java 开发环境,将会输出…

    Java 2023年5月20日
    00
  • 深入JAVA对象深度克隆的详解

    深入JAVA对象深度克隆的详解 对象深度克隆是指克隆一个对象及其子对象,同时新对象与原对象是互不干扰的,对新对象的任何修改都不会影响原对象。在Java中,实现对象深克隆通常使用“序列化”和“反序列化”技术。本篇文章将详细讲解如何实现Java对象的深度克隆。 实现Java对象深度克隆 方法一:序列化与反序列化实现克隆 序列化对象可以用ObjectOutputS…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部