美文网首页
单例模式的学习

单例模式的学习

作者: pianoboyfans | 来源:发表于2016-10-11 08:52 被阅读0次

一  单例模式的使用场景

单例模式用于确保某一个类有且只有一个实例,避免产生多个对象消耗过多的资源。所以当你所要定义的类会消耗较多的资源,例如访问IO和数据库等资源,就要考虑使用单例模式了。举个例子,在Android开发中出色的图片加载框架ImageLoader就使用了单例模式。因为ImageLoader中含有线程池、缓存系统、网络请求等等,比较耗费资源,如果没加载一张图片就去新建一个ImageLoader的实例则非常耗费资源,所以程序的设计者使用了单例模式,以让一个应用程序中有且仅有一个ImageLoader的实例。

二  单例模式的实现方法

实现单例模式主要有以下几个重点:

(1)构造方法不对外开放,一般为private

(2)通过静态方法返回实例

(3)确保类的实例有且仅有一个,特别是在多线程的环境下

(4)尽量确保线程安全

掌握内在思想后,就要开始实践了,单例模式的实现方法多种多样,且各有千秋,下面由简至繁一一举例,并且进行点评。

1、饿汉模式

public class Singleton {

     private Singleton() {}

                           private static final Singleton single = new Singleton();//静态工厂方法

public static Singleton getInstance() {

                               return single;}

                               }

上述这种实现方法叫饿汉模式,从代码中可以看到,外届只能通过Singleton.getInstance()方法获得Singleton的实例(single),而这个实例是静态对象,并且在声明的时候就初始化了,这就保证了Sigleton对象的唯一性,以后不再改变,所以天生是线程安全的。

2、懒汉模式

//懒汉式单例类.在第一次调用的时候实例化自己public class Singleton {

                           private Singleton() {}

                           private static  Singleton single=null;//静态工厂方法

public static synchronized Singleton getInstance() {

                               if (single == null) {

                                   single = new Singleton();}

                               return single;}

                               }

懒汉模式同样将构造函数私有化,对外提供Singleton.getInstance()方法获得Singleton的实例(single),不同的是饿汉模式中在类加载的时候就已经初始化了single实例,而懒汉模式中只有开发者调用了Singleton.getInstance()才去创建Single的实例对象(single),同时,细心地读者应该发觉Singleton.getInstance()方法加了一个synchronized 的关键字,这个关键字就是用来保证线程安全的。这种方法实现了单例模式也保证了线程安全,但是每次调用Singleton.getInstance()方法都需要进行同步以保证线程安全造成了很多不必要的同步开销,消耗资源。这个就是懒汉模式的缺点。

3、双重加锁(Double Check Lock)(比较推荐)

public class Singleton {

                           private Singleton() {}

                           private  volatile static  Singleton single=null;//静态工厂方法

public static Singleton getInstance() {

                               if (single == null) {

                                   synchronized (Singleton.class) {

                                       if (single== null) {

                                           single = new Singleton();}

                                   }

                               }

                               return single;}

                               }

Double Check Lock双重加锁,简称DCL,这种方式实现单例既能够在需要使用时才初始化单例,进行了同步保证了线程安全,也提高了资源的利用率。它的亮点在于Singleton.getInstance()方法中的对single进行了两层判空,第一层判空是为了避免不必要的同步,第二层判空是为了在single为null的情况下才创建实例。读者应该注意到单例对象single 定义添加了关键字volatile ,添加该字段是因为程序执行

single = new Singleton();

这个语句时其实做了三步工作,(1)分别是给Singleton的实例分配内存,(2)调用构造函数初始化成员字段,(3)将single对象指向分配的内存空间(single不再为null),由于Java虚拟机是乱序执行的,所以执行顺序可能是(1)(2)(3),也有可能是(1)(3)(2),在多线程情况下,假如(3)执行完成,(2)未执行,线程从A切换线程B,因为此时single不为null,所以线程B直接取走了未执行步骤(2)的single,因为此时single未调用构造函数初始化,所以B线程在使用single时会出错,此时双重加锁就会失效,上面添加的volatile关键字就是为了解决这个问题,它可以保证single每次都从主存中读取。但是volatile也会影响性能,一般来说在Android开发中,高并发的情况比较少见,所以在实际开发中大多数开发者选择把volatile 字段去掉。

4、静态内部类方式(也不错的)

public class Singleton {

                           private static class Holder {

                               private static final Singleton INSTANCE = new Singleton();}

                           private Singleton (){}

                           public static final Singleton getInstance() {

                               return Holder.INSTANCE;}

                               }

DCL虽然在一定程度上解决了资源消耗、多余的同步、线程安全等问题,但是在也会存在失效的可能,严重会导致程序崩溃。在《Java并发编程实践》中也谈到了这个问题,并直指这种优化是丑陋的不赞成使用,而提倡了上面这种静态内部类的实现方式。这种方式比上面1、2、3都好一些,既实现了线程安全,又避免了同步带来的性能影响,保证了单例对象的唯一性,同时延迟了单例的实例化。

仁者见仁智者见智,在Android开发实践中,通过阅读别人的代码发现,大部分开发者偏向于使用第三种双重加锁的实现方式,同时第四种方法得到圣书《Java并发编程实践》的力推,优点也是显而易见,所以个人推荐第三第四种实现方式。

相关文章

  • 设计模式系列教程之单例模式-原理介绍

    设计模式系列教程之单例模式-原理介绍 一:单例模式(Singleton)学习步骤 经典的单例模式原理: 本文出处:...

  • iOS-单例模式

    swift的单例设计模式 OC的单例设计模式 新学习一种单例思想

  • 【设计模式】单例模式

    学习文章 iOS设计模式 - 单例 SwiftSingleton 原理图 说明 单例模式人人用过,严格的单例模式很...

  • python 单例

    仅用学习参考 目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计...

  • 设计模式之单例模式

    单例设计模式全解析 在学习设计模式时,单例设计模式应该是学习的第一个设计模式,单例设计模式也是“公认”最简单的设计...

  • Android 单例模式学习

    android的单例模式学习 1 饿汉单例模式 优点 : 缺点 : 2.0 懒汉模式 优点 : 缺点 : 2.1 ...

  • 初识设计模式之单例模式

    此文为笔者个人的学习笔记,在学习部分博客、书籍、资料后所总结,仅供参考。 对单例模式的认识单例模式是什么单例模式的...

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • JAVA中各种单例模式的实现与分析

    单例模式是学习设计模式过程中最基本的一个设计模式,基本上一开始学习就会学到单例模式,实际上在java中实现单例模式...

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

网友评论

      本文标题:单例模式的学习

      本文链接:https://www.haomeiwen.com/subject/jlnvyttx.html