教你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日

相关文章

  • SpringMVC五大组件与执行原理分析总结

    SpringMVC五大组件与执行原理分析总结 SpringMVC是一个基于MVC架构的Web框架,它可以用于构建Web应用程序。SpringMVC框架提供了一组组件,包括控制器、视解析器、处理映射器、数据绑定、数据验证、异常处理等,可以帮助我们快速开发Web应用程序。在SpringMVC中,五大组件分别是:前端控制器、处理器映射器、处理器适配器、视图解析器、…

    Java 2023年5月18日
    00
  • Maven发布Jar包中文乱码解决方法

    下面我来详细讲解“Maven发布Jar包中文乱码解决方法”的完整攻略。 问题描述 当我们使用Maven打包发布Jar包时,有时会出现中文乱码的现象。这种现象出现的原因是在打包过程中,Maven使用的编码和实际项目使用的编码不一致,导致编码转换错误。因此,我们需要对这种问题进行解决。 解决方法 我们可以通过在Maven的pom.xml配置文件中添加如下代码来解…

    Java 2023年5月20日
    00
  • Java Mybatis框架由浅入深全解析下篇

    Java Mybatis框架是一个开源的持久层框架,可以帮助Java开发者快速有效地实现自己的关系型数据库操作。本篇文章是Java Mybatis框架由浅入深全解析的下篇,旨在帮助读者更深入地了解和掌握这一框架。本文的内容从以下几个方面进行讲解。 一、Mybatis框架的配置 Mybatis框架的配置包含两个部分,分别是SqlMapConfig.xml和Ma…

    Java 2023年6月1日
    00
  • java 解压与压缩文件夹的实例详解

    Java解压与压缩文件夹的实例详解 Java提供了许多用于压缩和解压缩文件的标准API,这些API可以通过java.util.zip包和java.util.jar包来实现。这些API可以让我们在Java中轻松地压缩和解压缩文件,并且在我们需要处理大量文件或需要将文件打包成压缩文件时非常有用。在本文中,我们将详细讲述如何使用Java的压缩和解压缩API。 压缩…

    Java 2023年5月20日
    00
  • Log4j新手快速入门教程

    Log4j新手快速入门教程攻略 介绍 Log4j是Java中广泛使用的开源日志记录组件。它可以将应用程序的日志输出到控制台、文件或网络,并可通过配置文件进行灵活的日志输出控制。本文将介绍Log4j的基本概念、使用方法和配置文件的格式,以帮助新手快速入门。 基本概念 Log4j提供了三个基本概念:Logger、Appender和Layout。 Logger:日…

    Java 2023年5月26日
    00
  • springboot注入servlet的方法

    下面是详细讲解Spring Boot注入Servlet的方法的完整攻略。 1. 添加Servlet API依赖 在Spring Boot中使用Servlet必须要先添加Servlet API依赖。可以在pom.xml文件中添加以下依赖项: <dependency> <groupId>javax.servlet</groupId&…

    Java 2023年5月19日
    00
  • java读取文件显示进度条的实现方法

    Java读取文件并显示进度条的实现方法可以分为以下几步: 步骤一:获取文件大小 File file = new File("文件路径"); long fileSize = file.length(); 步骤二:读取文件并更新进度条 FileInputStream fileInputStream = new FileInputStream(…

    Java 2023年5月20日
    00
  • java排序算法之冒泡排序

    Java排序算法之冒泡排序是一种简单的排序算法,它通过比较相邻两个元素的大小,如果前一个元素大于后一个元素,则交换它们的位置,重复这个过程直到整个数组排好序。 基本思路 遍历数组,将相邻两个元素进行比较,若前一个元素比后一个大,则交换它们的位置; 每遍历一轮,就可以找到当前最大或最小的元素,需要遍历数组长度减去已排序部分的次数。 代码实现 public st…

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