设计模式——单例模式

来源:互联网 发布:黄河商品交易软件 编辑:程序博客网 时间:2024/06/08 05:28

单例模式

  • 单利模式是应用最广泛的模式之一,也是初级工程师唯一会使用的一种设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个全局对象。

那些场景会用到单例模式

  • 例1:我们最常用的就是创建一个BaseActicity,而其他所有类都是集成此类。返回的类都是BaseActicity中的一个对象。
  • 例2:我们的线程池或者访问IO时都需要考虑使用单例模式

单例模式分析图

这里写图片描述

1、我们创建了一个单例类SingleText,这个时候我们的方法区中就会有一个对象mSingle等于堆内存中的new SingleText(),加入它在内存的地址为123456,那么mSingle 就指向此地址,如下;
  • mSingle = 123456;
2、我们在主类中的main方法中,由于不能通过new来创建SingleText的对象,只能使用“类.方法”的方式来获取单例类中的对象。如下:
  • SingleText s1 = SingleText.getInstance();
  • SingleText s2 = SingleText.getInstance();
  • SingleText s3 = SingleText.getInstance();
3、仔细看就会发现,不管你创建了多少对象,调用getInstance()方法返回的都是mSingle对象。所以他们指向的内存对象是一个。
  • s1 =123456
  • s2 =123456
  • s3 =123456
4、代码实例:打印出来指向同一个地址

这里写图片描述

单例实现需要注意三点

  1. 将构造函数私有化(private),禁止其他程序建立该类对象。
  2. 再类中创建一个本类对象,让其他程序可以访问到该类对象。
  3. 提供一个方法可以获取该对象。方便其他程序对自定义对象的访问。

单例有很多的实现方法

1、饿汉试(建议使用,不用担心线程问题)
public class Singleton {    private static Singleton instance=new Singleton();    private Singleton(){    }    public static Singleton getInstance(){        return instance;    }}

2、懒汉式(会出现线程问题)
public class Singleton {    private static Singleton instance=null;    private Singleton(){    }    public static Singleton getInstance(){        if(instance==null){            instance=new Singleton();        }        return instance;    }}
  • 出现的问题:
    这里写图片描述

3、懒汉式(加上了同步锁)
public class Singleton {    private static Singleton instance=null;    private Singleton(){    }    public static synchronized Singleton getInstance(){        if(instance==null){            instance=new Singleton();        }        return instance;    }}
  • 缺点:通过getInstance方法得到singleton实例的时候都有一个试图去获取同步锁的过程。而众所周知,加锁是很耗时的。能避免则避免。

4、懒汉式(加上了同步锁,并且两次非空判断,建议使用的方法)
public class Singleton {    private static Singleton instance=null;    private Singleton(){    }    public static Singleton getInstance(){        if(instance==null){            synchronized(Singleton.class){                if(instance==null){                    instance=new Singleton();                }            }        }        return instance;    }}
  • 优点:解决了线程安全,又保证了唯一性。
  • 缺点:用双重if判断,书写时候,容易出错。
5、静态内部类实现(现阶段最好的一种)
public class Singleton {    private Singleton(){    }    private static class SingletonHolder{        private final static Singleton instance=new Singleton();    }    public static Singleton getInstance(){        return SingletonHolder.instance;    }}
6、使用枚举来实现
public enum EnumSingleton{    INSTANCE;    public void doSomeThing(){    }}
  • 优点:写法简单,而且在任何情况下都是一个单例。前5种在反序列化时会出现重新创建对象的情况。所以要杜绝


懒汉式和饿汉式的区别

1、饿汉式:在程序启动或单件模式类被加载的时候(即声明静态对象时),单件模式实例就已经被创建。
2、懒汉式:当程序第一次访问单件模式实例时(即调用getInstance()时)才进行创建。

单例模式的优缺点

优点:

  • 1、由于单例中只有一个实例,减少了内存的开销。
  • 2、由于单例模式只生成一个实例,所以,减少性能消耗,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖关系对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留在内存的方式来解决。
  • 3、避免对资源的多闸弄,例如读写,只有一个实例存在内存,避免对一个资源文件的同时写操作。
  • 4、全局访问,资源共享。

缺点:

  • 1、单例模式一般情况没有接口,扩展很困难。
  • 2、单例对象如果持有Context,那么容易造成内存泄露。此时需要注意传递给单例对象的Context对象是Application Context.

总结:

  • 建议使用第4种和第5种,不管用那些都需要我们在使用的时候去慢慢的分析,任何知识都不可能根据一篇文章或者一段视频来了解所以然。因为我也是在学习中。如有不对地方,请在留言区指正。下一节:设计模式——工厂模式
0 0
原创粉丝点击