Java设计模式之单例模式

前言

单例模式是用的最广的设计模式,可以说随处可见。很多人也略知一二,可能让你写一个你花个十分钟思考一番也能写出来,可能你只是缺少了一个系统的认识,此文带你系统认识设计模式之单例模式。

1.1 概念

单例模式(Singleton),也叫单子模式,是一种常用的设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候,整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,显然,这种方式简化了在复杂环境下的配置管理。

特别地,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。事实上,这些应用都或多或少具有资源管理器的功能。例如,每台计算机可以有若干个打印机,但只能有一个 Printer Spooler(单例) ,以避免两个打印作业同时输出到打印机中。再比如,每台计算机可以有若干通信端口,系统应当集中 (单例)管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

综上所述,单例模式就是为确保一个类只有一个实例,并为整个系统提供一个全局访问点的一种方法。

1.2 理论基础

1.2.1 定义

确保每个类只有一个实例,并为整个系统提供一个全局访问点(向整个系统提供这个实例)

1.2.2 三要素

  1. 私有的构造方法
  2. 指向自己实例的私有静态引用
  3. 对外提供获取唯一实例的静态方法

1.2.3 单线程环境下两种经典实现

  1. 立即加载(饿汉式):在类加载初始化的时候就主动创建实例,优点是响应快;
  2. 延迟加载(懒汉式):等到真正使用时才去创建实例,不用时不去主动创建实例,优点是资源利用率高;

1.2.4 单例模式的优点

  1. 在内存中只有一个实例,节省内存空间;
  2. 避免频繁的创建销毁动作,可以提高性能;
  3. 避免对共享资源的多重占用,简化访问;
  4. 为整个系统提供一个全局访问点。

1.3 多线程环境下单例模式的实现

在单线程模式下,无论是饿汉式单例还是懒汉式单例,他们都能够正常工作。但是,在多线程环境下,情况就发生了变化:
由于饿汉式单线程天生就是线程安全的,可以直接用于多线程而不会出现问题;但懒汉式单例本身并非线程安全,因此就会出现多个实例的情况,这与单例模式的初衷是背离的。

这里重点阐述以下几个问题:

1.3.1 为什么饿汉式单例天生就是线程安全的?

// 饿汉式单例
public class Singleton1 {
   
 
    // 指向自己实例的私有静态引用,主动创建
    private static final Singleton1 INSTANCE = new Singleton1();
 
    // 私有的构造方法
    private Singleton1(){
   }
 
    // 以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton1 getSingleton1(){
   
        return INSTANCE;
    }
}

类加载的方式是按需加载,且只加载一次。因此,在上述单例类被加载时,就会实例化一个对象并交给自己的引用,供系统使用。换句话说,在线程访问单例对象之前就已经创建好了。再加上,由于一个类在整个生命周期中只会被加载一次,因此该单例类只会创建一个实例,也就是说,线程每次都只能也必定只可以拿到这个唯一的对象。因此就说,饿汉式单例天生就是线程安全的。

1.3.2 传统的懒汉式单例为什么是非线程安全的?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值