单例模式初级

  • 单例模式是一种创建型设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。

1、特点包括:

  1. 类内部控制实例的创建和访问,对外部隐藏实例的具体实现细节。
  2. 确保在整个应用程序中只有一个实例存在。
  3. 提供一个全局访问点,使得其他对象可以方便地访问该实例。

2、生活中的例子

那你来简单实现一下单例模式吧。
好的,面试官。(下面是懒汉创建方式)

假设我们有一个购物车类 ShoppingCart,它用于存放购物车中的商品信息。

public class ShoppingCart {
    private static ShoppingCart instance;

    private List<String> items;

    private ShoppingCart() {
        items = new ArrayList<>();
    }

    public static ShoppingCart getInstance() {
        if (instance == null) {
            instance = new ShoppingCart();
        }
        return instance;
    }

    public void addItem(String item) {
        items.add(item);
    }

    public void removeItem(String item) {
        items.remove(item);
    }

    public void displayItems() {
        System.out.println("Shopping Cart Items:");
        for (String item : items) {
            System.out.println(item);
        }
    }
}

在上述例子中,ShoppingCart 类的构造函数被声明为私有的,使得外部无法直接实例化该类。通过使用静态变量 instance 和静态方法 getInstance(),我们可以在需要使用 ShoppingCart 对象时获取到全局唯一的实例。

例如,在多个线程中调用 ShoppingCart.getInstance() 方法,都将返回同一个实例,保证了购物车对象的唯一性。可以通过调用 addItem()、removeItem() 和 displayItems() 方法来操作和展示购物车中的商品列表。这个例子中的购物车类就是一个简单的单例模式的实现。

3、单例模式创建方式:

  1. 饿汉式(Eager Initialization):在类加载时就创建实例对象,保证了线程安全。

  2. 懒汉式(Lazy Initialization):在第一次使用时创建实例对象,需要注意线程安全问题。

  3. 双重检查锁定(Double-Checked Locking):在懒汉式的基础上增加了同步锁,实现了线程安全。

  4. 静态内部类(Static Inner Class):利用类的加载机制保证了线程安全,且在调用getInstance()方法时才会加载内部类,实现了懒加载。

4、讲一下饿汉式和懒汉式的区别,各自的优缺点

饿汉式和懒汉式都是单例模式的创建方式,它们的主要区别在于对象的创建时机。

  1. 饿汉式:

    • 在类加载时就创建了对象实例,无论是否需要使用该实例。
    • 在类加载时就初始化,所以线程安全。
    • 实现简单,代码可读性好。
    • 优点:线程安全,实现简单。
    • 缺点:可能会浪费资源,因为可能在程序中并未使用该实例。
  2. 懒汉式:

    • 延迟创建对象实例,只有在需要使用时才进行初始化。
    • 在多线程环境下,可能会导致竞态条件(race condition),从而导致创建多个实例。
    • 需要使用同步机制(如synchronized关键字)来保证线程安全。
    • 优点:延迟加载,节省资源。
    • 缺点:线程不安全,需要额外的同步机制。

总结:

  • 饿汉式适合在程序启动时就需要创建实例,并且创建实例的过程较为简单的情况下使用。
  • 懒汉式适合在需要时才创建实例,并且创建实例的过程较为复杂的情况下使用。

5、那如何解决懒汉式中的线程安全问题

  • 使用synchronized关键字同步方法或同步代码块
  • 使用双重检查锁定和静态内部类的方式来创建单例。
  • 双重检查锁定可以在多线程环境下保证线程安全,并且减少了不必要的同步开销;
  • 而静态内部类方式则利用了类加载的特性,保证了线程安全且延迟加载。

6、模式优点:

  1. 保证只有一个实例存在,节省了系统资源。
  2. 提供了对唯一实例的全局访问点,方便其他对象对该实例的调用。
  3. 避免了多个实例之间的冲突和数据不一致。
  4. 在需要频繁创建和销毁对象的场景中,可以大大提高性能。

7、模式缺点:

  1. 违反了单一职责原则,因为单例类负责创建对象同时还负责管理全局状态,可能导致代码复杂性增加。
  2. 单例类的扩展性较差,因为单例类的行为和状态在整个系统中是固定的,难以进行扩展和修改。
  3. 单例模式在多线程环境下需要考虑线程安全问题,需要额外的处理来保证线程安全。
  4. 单例模式的使用会增加代码的耦合性,使代码难以进行单元测试。

8、应用场景:

  1. 当需要确保系统中只有一个实例存在时,可以使用单例模式。例如,日志记录器、数据库连接池等。
  2. 当某个实例需要被频繁访问时,可以使用单例模式,以避免反复创建和销毁实例,提高性能。
  3. 当多个实例需要共享一些数据或资源时,可以使用单例模式,以保证数据的一致性。
  4. 当某个对象需要被全局访问时,可以使用单例模式,以方便其他对象对该对象的调用。

总之,单例模式在某些场景下可以提供一种简单、方便和高效的对象管理方式,但同时也需要注意其缺点和适用场景,避免不必要的使用。

我只是简单总结一哈,方便面试哦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白夜的月亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值