创建型模式之单例设计模式

红烧土豆泥
• 阅读 1522

什么是单例设计模式? 顾名思义,只有一个实例。 单例模式它主要是确保一个类只有一个实例,并且可以提供一个全局的访问点。 废话少说,直接上干货了~

单例模式之饿汉式 所谓饿汉式,顾名思义,“ 它很饿 ”。所以说,它一旦被加载进来,就会直接实例化一个对象。 例如:

  class Singleton {
    private static final Singleton SINGLE = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SINGLE;
    }

    public void print() {
        System.out.println("hello,我是饿汉~ 哇咔咔~");
    }
}

接下来编写一个测试类

  @Test
    public void TestSingleton() {
        Singleton s = Singleton.getInstance();
        s.print();
    }

运行效果: 创建型模式之单例设计模式

结果异常顺利,就这样结束了吗?肯定不会就这样简单啦!我们再来看一下它在多线程的情况下运行效果如何?

  class Singleton {
    private static final Singleton SINGLE = new Singleton();

    private Singleton() {
        System.out.println("我出来啦~");
    }

    public static Singleton getInstance() {
        return SINGLE;
    }

    public void print() {
        System.out.println("hello,我是饿汉~ 哇咔咔~");
    }
}

测试类:

  @Test
    public void TestSingleton() {
        for (int i = 0; i < 3; i++) {
            new Thread(()->{
                Singleton s = Singleton.getInstance();
                s.print();
            }).start();
        }
    }

结果: 创建型模式之单例设计模式 可以看到,测试结果还是异常丝滑。

那让我们再来看看它兄弟 --> 单例模式之懒汉式 一听他名字,就知道它比较懒,肯定一上来就不会进行实例化,而是先判断,先问一下你有对象了吗?如果没有的话,再给你分配。 所以说,它的写法应该是:

  class Singletonss{
    private static Singletonss SING = null;

    private Singletonss() {
        System.out.println("我是懒汉,我出来啦~");
    }

    public static Singletonss getInstance() {
        if(SING == null) {
            SING = new Singletonss();
        }
        return SING;
    }

    public void print() {
        System.out.println("hello,我是懒汉~ 哇咔咔~");
    }

}

下面是一个测试类:

  @Test
    public void TestSingleton() {
        Singletonss s = Singletonss.getInstance();
        s.print();
    }

看一下运行结果: 创建型模式之单例设计模式 貌似是一切正常,风平浪静,没什么太大问题~ 然后,让我们再来偷偷瞅一下它在多线程的情况下是什么妖怪吧~ 还是用上面的懒汉式代码,然后编写一个测试

  @Test
    public void TestSingleton() {
        for(int i=0;i<3;i++) {
            new Thread(()->{
                Singletonss s = Singletonss.getInstance();
                s.print();
            }).start();
        }
    }

创建型模式之单例设计模式 是不是被突然跳出来的饿汉吓到了,我才开启了三个线程,他竟然出来了三次~ 让我们分析一下是什么原因吧!可能细心的小伙伴们已经想到,多线程情况下,每个线程都会竞相抢夺资源,所以说第一个线程它在执行if判断但还未进行new的时候,别的线程也可能进入了if判断,所以说就会出现饿汉单例被实例化多次的情况,如何解决勒,有的人可能回想直接给那个方法加synchronized关键字,每次只允许一个线程进入。没错,这样是可以解决掉这问题,但是,如果给方法加了同步,也就意味着,线程资源来到这之后,只能先进入一个,别的需要排队等待这,如果只有一两个线程还好,如果说有几千个线程在这,无疑这样会大大浪费了资源,拖慢了程序的进度,所以这种方法不是最优的。那如果是给if判断加同步嘞?

  public static Singletonss getInstance() {
        synchronized (Singletonss.class) {
            if(SING == null) {
                SING = new Singletonss();
            }
        }
        return SING;
    }

感觉上还是蛮好的,但是与上个方法没太大区别。那,这,,,咋整哇~ 其实我们可以让每个先到的线程先进入if判断,然后开启同步,然后再进行一次判断,让先来的去实例化,后来的一看已经被实例化好了,就可以直接返回了。这样可以很大程度上减少线程等待时间。具体实现代码如下:

  class Singletons {

    private static volatile Singletons single = null;

    private Singletons() {
        System.out.println("我是懒汉,我出来啦~");
    }

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

    public void print() {
        System.out.println("hello,我是懒汉~ 哇咔咔~");
    }
}

测试类:

  @Test
    public void TestSingleton() {
        for(int i=0;i<3;i++) {
            new Thread(()->{
                Singletons s = Singletons.getInstance();
                s.print();
            }).start();
        }
    }

再来看一下与运行结果: 创建型模式之单例设计模式 一切正常

点赞
收藏
评论区
推荐文章
3A网络 3A网络
2年前
Golang 常见设计模式之单例模式
之前我们已经看过了Golang常见设计模式中的装饰和选项模式,今天要看的是Golang设计模式里最简单的单例模式。单例模式的作用是确保无论对象被实例化多少次,全局都只有一个实例存在。根据这一特性,我们可以将其应用到全局唯一性配置、数据库连接对象、文件访问对象等。Go语言实现单例模式的方法有很多种,下面我们就一起来看一下。饿汉式饿汉式实现单例模式非
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java设计模式1
1:单例模式简介  单例模式是一种常用的软件设计模式,它确保某个类只有一个实例,而且自行实例化并向整个系统提供唯一的实例。总而言之就是在系统中只会存在一个对象,其中的数据是共享的  特点:    单例类只能有一个实例,所以一般会用static进行修释。    单例类必须自己创建自己的唯一实例。也就是在类中要new一个自己。    单例类必
Wesley13 Wesley13
3年前
java 23种设计模式(五、单例模式)
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。单例模式的结构  单例模式的特点:单例类只能有一个实例。单例类必须自己创建自己的唯一实例。单例类必须给所有其他对象提供这一实例。  饿汉式单例类publicclassEagerSingleton
Wesley13 Wesley13
3年前
JAVA设计模式之单例设计模式
    单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。  在JAVA中实现单例,必须了解JAVA内存机制,JAVA中实例对象存在于堆内存中,若要实现单例,必须满足两个条件:  1.限制类实例化对象。即只能产生一个对象。
Wesley13 Wesley13
3年前
Java单例模式
什么是单例模式  单例模式是在程序中,一个类保证只有一个实例,并提供统一的访问入口。为什么要用单例模式节省内存节省计算如对象实例中的一样的,那就不用每次都创建一个对象方便管理因为单例提供一个统一的访问入口,不需要创建N多个对象,很多工具类都用了单例实现,如日志、字符串工具类
Wesley13 Wesley13
3年前
PHP单例模式(精讲)
首先我们要明确单例模式这个概念,那么什么是单例模式呢?单例模式顾名思义,就是只有一个实例。作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类我们称之为单例类。单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例
Stella981 Stella981
3年前
C#设计模式(1)——单例模式(Singleton)
单例模式即所谓的一个类只能有一个实例,也就是类只能在内部实例一次,然后提供这一实例,外部无法对此类实例化。单例模式的特点:1、只能有一个实例;2、只能自己创建自己的唯一实例;3、必须给所有其他的对象提供这一实例。普通单例模式(没有考虑线程安全)  ///<summary///单例模式
Wesley13 Wesley13
3年前
(面试常问)4种单例设计模式的总结(内含代码以及分析)
单例设计模式:  单例模式,是一种常见的软件设计模式.在它的核心结构中只包含了一个被称为单例的特殊类.通过单例模式可以保证系统中只有该类的一个实例对象.优点:  实例控制:单例模式会阻止其它对象实例化其自己的单例对象的副本,从而确保所有对象都访问的是唯一的实例   灵活性:因为类控制了实例化过程,所以类可以很灵活的更改实
Wesley13 Wesley13
3年前
23种设计模式(1):单例模式
定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。类型:创建类模式类图:!23种设计模式(1):单例模式第1张|快课网(http://static.oschina.net/uploads/img/201407/05200605_0dij.gif"23种设计模式(1):单例模式