JAVA设计模式1:单例模式,确保每个类只能有一个实例

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: JAVA设计模式1:单例模式,确保每个类只能有一个实例

本文讲解了 Java 设计模式中的单例模式,并给出了样例代码,单例模式,确保每个类只能有一个实例,并提供一个全局访问点来获取该实例。

一、单例模式是什么

Java 中的单例模式是一种设计模式,它确保某个类只能有一个实例,并提供一个全局访问点来获取该实例

实现单例模式可以有多种方式,其中最常用的方式有两种:懒汉式饿汉式

1.1 懒汉式单例模式

懒汉式在首次调用获取实例的方法时才创建对象

以下是一种常见的懒汉式单例模式的实现方式,请同学们认真学习。

public class Singleton {
       private static Singleton instance;
       private Singleton() {
           // 私有构造方法
       }
       public static synchronized Singleton getInstance() {
           if (instance == null) {
               instance = new Singleton();
           }
           return instance;
       }
   }

提示:上述实现在多线程环境下可以正常工作,但是由于在获取实例的方法上加了同步锁,会导致性能下降。

1.2 饿汉式单例模式

饿汉式在类加载时就创建对象,因此可以保证在任何时候都只有一个实例

以下是一种常见的饿汉式单例模式的实现方式,请同学们认真学习。

public class Singleton {
       private static final Singleton instance = new Singleton();
       private Singleton() {
           // 私有构造方法
       }
       public static Singleton getInstance() {
           return instance;
       }
   }

提示:饿汉式可以确保在多线程环境下也能正常工作,但可能会造成资源浪费,因为实例在类加载时就创建。

1.3 懒汉/饿汉单例小结

无论使用懒汉式还是饿汉式,单例模式都需要注意线程安全性、序列化和反射等方面的问题。如果需要更好的线程安全性和更高的性能,可以考虑使用双重检查锁定或静态内部类等方式实现单例模式。


二、单例模式有哪些

在第一章简单介绍了单例模式,接下来进行详细介绍,并给出详细代码。

在 Java 中,实现单例模式的方式有以下几种。

2.1 懒汉式(Lazy Initialization)单例模式

public class LazySingleton {
    private static LazySingleton instance;
    private LazySingleton() {
        // 私有构造方法
    }
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

2.2 饿汉式(Eager Initialization)单例模式

public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();
    private EagerSingleton() {
        // 私有构造方法
    }
    public static EagerSingleton getInstance() {
        return instance;
    }
}

2.3 双重检查锁定(Double-Checked Locking)单例模式

public class DoubleCheckedSingleton {
    private volatile static DoubleCheckedSingleton instance;
    private DoubleCheckedSingleton() {
        // 私有构造方法
    }
    public static DoubleCheckedSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckedSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckedSingleton();
                }
            }
        }
        return instance;
    }
}

2.4 静态内部类(Static Inner Class)单例模式

public class StaticInnerSingleton {
    private StaticInnerSingleton() {
        // 私有构造方法
    }
    private static class SingletonHolder {
        private static final StaticInnerSingleton instance = new StaticInnerSingleton();
    }
    public static StaticInnerSingleton getInstance() {
        return SingletonHolder.instance;
    }
}

以上是常用的几种单例模式的实现方式,在实现单例模式时,需要考虑线程安全性、序列化和反射等方面的问题。


三、单例模式的应用场景

单例模式在以下 5 55 情况下常常被使用,请同学们认真学习。

  1. 资源共享:当多个对象需要共享同一个资源时,使用单例模式可以确保只有一个实例被创建,从而避免资源的重复创建与浪费。
  2. 配置信息:单例模式可以用于管理全局的配置信息,保证配置信息的一致性和唯一性。
  3. 日志记录器:在日志记录器的场景下,单例模式可以确保只有一个日志记录器实例,方便统一管理和记录日志。
  4. 数据库连接池:在数据库连接池的实现中,使用单例模式可以确保只有一个连接池被创建,从而避免连接资源的滥用和浪费。
  5. 线程池:在多线程场景下,使用单例模式可以确保只有一个线程池实例,方便管理和控制线程资源。

总的来说,单例模式适用于需要在系统中全局访问且只有一个实例的场景,可以提供一种简洁、方便、安全的解决方案。然而,过度使用单例模式可能导致代码的耦合性增加,应谨慎使用。


四、单例模式面试题

  1. 请解释什么是单例模式,它的作用是什么?
  2. 请列举几种常见的单例模式的实现方式,并分别说明它们的优缺点。
  3. 如何确保在多线程环境下单例模式的正确工作?
  4. 单例模式是否能被继承和被克隆?
  5. 如何防止通过反射来破坏单例模式的实现?
  6. 单例模式是否有线程安全问题?如果有,如何解决?
  7. 饿汉式和懒汉式单例模式的区别是什么?在什么情况下使用哪种方式?
  8. 单例模式适用于哪些场景?请举例说明。
  9. 单例模式的优点和缺点分别是什么?
  10. 除了单例模式,还有哪些相关的设计模式?

五、总结

本文讲解了 Java 设计模式中的单例模式,并给出了样例代码,在下一篇博客中,将讲解 Java 工厂方法模式。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
1天前
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
|
1月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
46 8
|
1月前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
65 1
|
1月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
38 4
|
1月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
Java Android开发
Eclipse 创建 Java 类
Eclipse 创建 Java 类
26 0
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
1月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
1月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式