设计模式之单例模式

单例模式

1. 介绍

单例模式,就是保证在整个软件系统中,对某个类只能存在一个对象实例 ,并且该类只提供一个能够取得其对象实例的方法(静态方法)。

单例模式可以节省系统资源,保证线程同步。

常用于经常创建和销毁的对象、创建和销毁耗时过多的对象、经常被使用的对象、工具类对象、频繁访问数据库或文件的对象。


2. 单例模式的多种方式

  1. 饿汉式
    1. 静态常量实现
    2. 静态代码块实现
  2. 懒汉式(线程不安全)
  3. 懒汉式(线程安全)
    1. 双重检查
    2. 静态内部类
  4. 枚举

2.1 饿汉式

静态常量的饿汉式中,直接通过new成员变量来创建单例的实例

静态代码块的饿汉式中,则是放在静态代码块中实例化的


步骤
  1. 构造器私有化(防止new),在类的内部创建对象
  2. 对外暴露一个静态公共方法获取类(getInstance方法)

优缺点

优点:写法简单,可避免线程同步问题

缺点:类加载时实例化,没有达到懒加载(Lazy Loading)的效果,存在资源浪费问题


2.2 懒汉式

判断单例对象是否为null,如果为null则实例化对象并返回,否则直接返回。

优缺点

优点:实现了懒加载,但是只能在单线程下使用

缺点:if (实例 == null) { 创建实例 }这样的判断语句不是线程安全的,可能会产生多个实例


线程安全-同步方法

getInstance方法使用synchronized关键字

优点:线程安全

缺点:效率低,实际开发不推荐


2.3 双重检查

优点:线程安全,多线程经常运用,效率较高

使用volatile关键字,其作用是使被修饰的变量的修改可以立即同步到内存(可见性

class Singleton {
    private static volatile Singleton singleton;
    private Singleton() {}
    private static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                // 在你获取到锁之后,可能对象已经创建好了,需要再次判断
                if (singleton == null) {
                    singleton == new Singleton();
                }
            }
        }
        return singleton;
    }
}

2.4 静态内部类

静态内部类的特点:

  1. 外部类被加载时,内部类尚未被加载
  2. 静态内部类的属性初始化时,JVM保证线程安全
class Singleton {
    private Singleton() {}
    private static class SingletonInstance {
        // SingletonInstance加载时实例化,线程安全
        private static final Singleton INSTANCE = new Singleton();
    }
    private static Singleton getInstance() {
        // 用的时候才加载SingletonInstance
        return SingletonInstance.INSTANCE;
    }
}

优点:线程安全,效率高


2.4 枚举

不仅能避免多线程同步问题,还能防止反序列化重新创建的对象

Effective Java的作者提倡的方式,推荐使用,但局限性大

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值