vlambda博客
学习文章列表

白话设计模式-烂大街的单例模式

说到单例模式,我相信再看的都不会陌生,毕竟都烂大街了。

这篇文章,你将会看到:

1.什么是单例模式

2.单例模式要注意什么

3.单例模式的5种方式具体实现


白话设计模式-烂大街的单例模式

一.什么是单例模式。

就好比一个人,每次叫他(调用)的时候,都是同一个对象,并不是一个新的对象。单例模式只会有一个实例,那就是你,你将会是给别人提供的唯一的一个实例。

一个实例&&唯一 = 单例模式


白话设计模式-烂大街的单例模式
白话设计模式-烂大街的单例模式

二.单例模式要注意什么

1.要保证一个实例,在多线程环境下,就必须要保证线程安全

2.尽可能少的暂用资源,也就是懒加载lazy


三.单例模式的5种方式


这5种方式可以总结为:饿Double,在内部枚举


1. 饿汉模式

饿汉就是类加载就创建实例,这个实例一直在。

含义:饿就饿在管你吃不吃,先new起来给你准备好。所以不用考虑线程

缺点:占用内存

适用:占用内存小的对象

public class Singleton{ private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton newInstance(){ return instance; }}


2.懒汉模式

懒汉就是用到的时候再去创建实例

含义:我就是懒,你叫我去做,我再去做,我才不会给你提前准备好呢。

缺点:需要考虑线程安全,下面的懒汉demo是不安全的

适用:使用少,占内存大的对象

public class Singleton{ private static Singleton instance = null; private Singleton(){} public static Singleton newInstance(){ if(null == instance){  instance = new Singleton(); } return instance; }}


3.Double check(面试常问)

升级的懒汉模式,解决了线程安全问题,但是又不像直接加synchronized那么笨重,重点在于一个double check

为什么需要double check?

第一个check:防止已创建的对象进入,挡掉了大部分进入。

第二个check:在两个线程都同时达到synchronized的时候,线程A执行完毕并new了对象,这个时候排到线程B进入,如果没有判断,则又会new对象。

为什么要加volatile?

防止指令重排。对于volatile通过MESI缓存一致性协议,通俗的讲就是在某个线程改变值的情况下,会去通知其他线程值改变了,再写进内存里,所以它能保证执行的顺序性。

volatile关键字详细讲解将会在未来的并发编程专栏里为大家呈现。

public class Singleton { private static volatile Singleton instance = null;//volatile private Singleton() {} public static Singleton newInstance() { if (null == instance) {// Single Checked synchronized (Singleton.class) { if (null == instance) {// Double checked instance = new Singleton(); } } } return instance; }}


4.内部类

内部类只会在用的时候才会去new,解决了饿汉的内存占用,又解决了懒汉的线程安全问题

public class Singleton { private static class SingletonHolder { public static Singleton instance = new Singleton(); } private Singleton() {} public static Singleton newInstance() { return SingletonHolder.instance; }}

5.枚举

通过Singleton.INSTANCE获得单例对象,但是它的缺点和饿汉一样,就是占用内存。

但是它比其他方式好的就是:有效避免的反序列化来创造新的对象。

public enum Singleton { INSTANCE;}


今天给大家讲了最简单的单例模式,以及5种创建方式,只要记住饿Double,在内部枚举,以及double check相关的两个问题,那么你在单例模式的面试都不会有什么问题了。



喜欢本文章的,可以点一下关注按钮,你们的支持就是我最大的动力。