架构师之路--单例模式

目录

介绍

定义

使用场景

实现方式

     1、懒汉模式

     2、Double Check实现单例

     3、静态内部类方式

     4、枚举方式


介绍

     本节我们来看看设计模式中使用场景最多的单例模式,网上也有很多的知识,各种单例模式的写法,对于我们日常的工作,已经足够了。单例模式的类必须保证该模式的对象只有一个实例的存在,许多时候,系统只需要拥有一个全局对象,这样有利于我们协调系统整体的行为,比如在一个应用中,应该只有一个ImageLoader实例,这个ImageLoader中又含有线程池、缓存系统、网络请求,很消耗资源,因此没有理由让它构造多个对象,这种不能自由构造对象的情况,就是单例模式的使用场景。

定义

     确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

使用场景

     确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有且只有一个实例。例如,创建一个对象需要消耗的资源过多,像访问IO和数据库等资源,这时就需要考虑单例模式。

实现方式

     1、懒汉模式

     懒汉模式是声明一个静态对象,并且在用户第一次调用getInstance方法时进行初始化,示例代码如下:

public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }

        return instance;
    }
}

     这种方式通过在getInstance方法上添加synchronized关键字保证同步,这也是保证对象唯一的手段,但是每次调用该方法都会同步,这样就会产生多余的资源消耗,所以一般不建议使用。

     2、Double Check实现单例

     DCL方式实现单例的优点是既能够在需要时才初始化,又能免保证线程安全,且单例对象初始化后每次调用getInstance可以不需要同步锁,代码如下:

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}

     该方式的亮点就在getInstance方法中,可以看到该方法中对instance实例进行了两次判空,第一层主要是为了避免不必要的同步,第二层判断是为了首次进来时进行实例的创建。DCL模式能够在需要时才实例化对象,并且保证对象的唯一性,除非我们的代码在并发场景很复杂或者低于JDK6版本下使用,这种方式就能够满足我们的需求了。

     3、静态内部类方式

     DCL方式在一定程序上解决了资源消耗多、多余同步、线程安全的问题,但是某些场景下会出现失效的问题,这被称为双重锁定失效。静态内部类的实现方式如下:

public class Singleton {
    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.sInstance;
    }

    private static class SingletonHolder {
        private static final Singleton sInstance = new Singleton();
    }
}

     当第一次加载Singleton类时并不会初始化sInstance,只有一第一次调用getInstance方法时才会导致sInstance被初始化,因此第一次调用getInstance方法会导致虚拟机加载SingletonHolder类,这种方式不仅能够确保线程安全,而且能够保证对象唯一,同时也延迟了实例化,所以这是推荐使用的实现方式。

     4、枚举方式

     枚举方式的实现如下:

public enum  Singleton {
    INSTANCE;

    public void process() {

    }
}

     此外还有容器方式,我们就不列举了,一般使用DCL或者静态内部类方式就可以了。   

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

红-旺永福

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

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

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

打赏作者

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

抵扣说明:

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

余额充值